1 /*
2     libzint - the open source barcode library
3     Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
4 
5     Redistribution and use in source and binary forms, with or without
6     modification, are permitted provided that the following conditions
7     are met:
8 
9     1. Redistributions of source code must retain the above copyright
10        notice, this list of conditions and the following disclaimer.
11     2. Redistributions in binary form must reproduce the above copyright
12        notice, this list of conditions and the following disclaimer in the
13        documentation and/or other materials provided with the distribution.
14     3. Neither the name of the project nor the names of its contributors
15        may be used to endorse or promote products derived from this software
16        without specific prior written permission.
17 
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28     SUCH DAMAGE.
29  */
30 /* vim: set ts=4 sw=4 et : */
31 
32 #include "testcommon.h"
33 
test_large(int index,int debug)34 static void test_large(int index, int debug) {
35 
36     struct item {
37         int symbology;
38         int option_2;
39         char *pattern;
40         int length;
41         int ret;
42         int expected_rows;
43         int expected_width;
44     };
45     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
46     struct item data[] = {
47         /*  0*/ { BARCODE_MSI_PLESSEY, -1, "9", 65, 0, 1, 787 },
48         /*  1*/ { BARCODE_MSI_PLESSEY, -1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
49         /*  2*/ { BARCODE_MSI_PLESSEY, 1, "9", 65, 0, 1, 799 }, // 1 mod-10 check digit
50         /*  3*/ { BARCODE_MSI_PLESSEY, 1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
51         /*  4*/ { BARCODE_MSI_PLESSEY, 2, "9", 65, 0, 1, 811 }, // 2 mod-10 check digits
52         /*  5*/ { BARCODE_MSI_PLESSEY, 2, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
53         /*  6*/ { BARCODE_MSI_PLESSEY, 3, "9", 65, 0, 1, 799 }, // 1 mod-11 check digit
54         /*  7*/ { BARCODE_MSI_PLESSEY, 3, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
55         /*  8*/ { BARCODE_MSI_PLESSEY, 3, "3", 65, 0, 1, 811 }, // 1 mod-11 double check digit "10"
56         /*  9*/ { BARCODE_MSI_PLESSEY, 3, "3", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
57         /* 10*/ { BARCODE_MSI_PLESSEY, 4, "9", 65, 0, 1, 811 }, // 1 mod-11 and 1 mod-10 check digit
58         /* 11*/ { BARCODE_MSI_PLESSEY, 4, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
59         /* 12*/ { BARCODE_MSI_PLESSEY, 4, "3", 65, 0, 1, 823 }, // 1 mod-11 double check digit "10" and 1 mod-10 check digit
60         /* 13*/ { BARCODE_MSI_PLESSEY, 4, "3", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
61         /* 14*/ { BARCODE_MSI_PLESSEY, 5, "9", 65, 0, 1, 799 }, // 1 NCR mod-11 check digit
62         /* 15*/ { BARCODE_MSI_PLESSEY, 5, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
63         /* 16*/ { BARCODE_MSI_PLESSEY, 6, "9", 65, 0, 1, 811 }, // 1 NCR mod-11 and 1 mod-10 check digit
64         /* 17*/ { BARCODE_MSI_PLESSEY, 6, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
65         /* 18*/ { BARCODE_PLESSEY, -1, "A", 65, 0, 1, 1107 },
66         /* 19*/ { BARCODE_PLESSEY, -1, "A", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
67     };
68     int data_size = ARRAY_SIZE(data);
69     int i, length, ret;
70     struct zint_symbol *symbol;
71 
72     char data_buf[4096];
73 
74     testStart("test_large");
75 
76     for (i = 0; i < data_size; i++) {
77 
78         if (index != -1 && i != index) continue;
79 
80         symbol = ZBarcode_Create();
81         assert_nonnull(symbol, "Symbol not created\n");
82 
83         testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
84         assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
85 
86         length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
87 
88         ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
89         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
90 
91         if (ret < ZINT_ERROR) {
92             assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
93             assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
94         }
95 
96         ZBarcode_Delete(symbol);
97     }
98 
99     testFinish();
100 }
101 
test_hrt(int index,int debug)102 static void test_hrt(int index, int debug) {
103 
104     struct item {
105         int symbology;
106         int option_2;
107         char *data;
108 
109         char *expected;
110     };
111     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
112     struct item data[] = {
113         /*  0*/ { BARCODE_MSI_PLESSEY, -1, "1234567", "1234567" },
114         /*  1*/ { BARCODE_MSI_PLESSEY, 0, "1234567", "1234567" },
115         /*  2*/ { BARCODE_MSI_PLESSEY, 1, "1234567", "12345674" },
116         /*  3*/ { BARCODE_MSI_PLESSEY, 1 + 10, "1234567", "1234567" },
117         /*  4*/ { BARCODE_MSI_PLESSEY, 1, "9999999999", "99999999990" },
118         /*  5*/ { BARCODE_MSI_PLESSEY, 2, "1234567", "123456741" },
119         /*  6*/ { BARCODE_MSI_PLESSEY, 2 + 10, "1234567", "1234567" },
120         /*  7*/ { BARCODE_MSI_PLESSEY, 2, "9999999999", "999999999900" },
121         /*  8*/ { BARCODE_MSI_PLESSEY, 3, "1234567", "12345674" },
122         /*  9*/ { BARCODE_MSI_PLESSEY, 3 + 10, "1234567", "1234567" },
123         /* 10*/ { BARCODE_MSI_PLESSEY, 3, "9999999999", "99999999995" },
124         /* 11*/ { BARCODE_MSI_PLESSEY, 4, "1234567", "123456741" },
125         /* 12*/ { BARCODE_MSI_PLESSEY, 4 + 10, "1234567", "1234567" },
126         /* 13*/ { BARCODE_MSI_PLESSEY, 4, "9999999999", "999999999959" },
127         /* 14*/ { BARCODE_MSI_PLESSEY, 5, "1234567", "12345679" },
128         /* 15*/ { BARCODE_MSI_PLESSEY, 5 + 10, "1234567", "1234567" },
129         /* 16*/ { BARCODE_MSI_PLESSEY, 5, "9999999999", "999999999910" },
130         /* 17*/ { BARCODE_MSI_PLESSEY, 6, "1234567", "123456790" },
131         /* 18*/ { BARCODE_MSI_PLESSEY, 6 + 10, "1234567", "1234567" },
132         /* 19*/ { BARCODE_MSI_PLESSEY, 6, "9999999999", "9999999999109" },
133         /* 20*/ { BARCODE_MSI_PLESSEY, 1, "123456", "1234566" },
134         /* 21*/ { BARCODE_MSI_PLESSEY, 2, "123456", "12345666" },
135         /* 22*/ { BARCODE_MSI_PLESSEY, 3, "123456", "1234560" },
136         /* 23*/ { BARCODE_MSI_PLESSEY, 4, "123456", "12345609" },
137         /* 24*/ { BARCODE_MSI_PLESSEY, 3, "2211", "221110" }, // Mod-11 check digit '10'
138         /* 25*/ { BARCODE_MSI_PLESSEY, 3 + 10, "2211", "2211" }, // Mod-11 check digit '10'
139         /* 26*/ { BARCODE_MSI_PLESSEY, 4, "2211", "2211100" },
140         /* 27*/ { BARCODE_MSI_PLESSEY, 4 + 10, "2211", "2211" },
141         /* 28*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", "0123456789ABCDEF" },
142     };
143     int data_size = ARRAY_SIZE(data);
144     int i, length, ret;
145     struct zint_symbol *symbol;
146 
147     testStart("test_hrt");
148 
149     for (i = 0; i < data_size; i++) {
150 
151         if (index != -1 && i != index) continue;
152 
153         symbol = ZBarcode_Create();
154         assert_nonnull(symbol, "Symbol not created\n");
155 
156         length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
157 
158         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
159         assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 %s\n", i, ret, symbol->errtxt);
160 
161         assert_zero(strcmp((char *) symbol->text, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->text, data[i].expected);
162 
163         ZBarcode_Delete(symbol);
164     }
165 
166     testFinish();
167 }
168 
test_input(int index,int debug)169 static void test_input(int index, int debug) {
170 
171     struct item {
172         int symbology;
173         int option_2;
174         char *data;
175         int ret;
176         int expected_rows;
177         int expected_width;
178     };
179     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
180     struct item data[] = {
181         /*  0*/ { BARCODE_MSI_PLESSEY, -1, "1", 0, 1, 19 },
182         /*  1*/ { BARCODE_MSI_PLESSEY, -1, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
183         /*  2*/ { BARCODE_MSI_PLESSEY, -2, "1", 0, 1, 19 }, // < 0 ignored
184         /*  3*/ { BARCODE_MSI_PLESSEY, 7, "1", 0, 1, 19 }, // > 6 ignored
185         /*  4*/ { BARCODE_PLESSEY, -1, "A", 0, 1, 83 },
186         /*  5*/ { BARCODE_PLESSEY, -1, "G", ZINT_ERROR_INVALID_DATA, -1, -1 },
187     };
188     int data_size = ARRAY_SIZE(data);
189     int i, length, ret;
190     struct zint_symbol *symbol;
191 
192     testStart("test_input");
193 
194     for (i = 0; i < data_size; i++) {
195 
196         if (index != -1 && i != index) continue;
197 
198         symbol = ZBarcode_Create();
199         assert_nonnull(symbol, "Symbol not created\n");
200 
201         length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
202 
203         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
204         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
205 
206         if (ret < ZINT_ERROR) {
207             assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
208             assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
209         }
210 
211         ZBarcode_Delete(symbol);
212     }
213 
214     testFinish();
215 }
216 
test_encode(int index,int generate,int debug)217 static void test_encode(int index, int generate, int debug) {
218 
219     struct item {
220         int symbology;
221         int option_2;
222         char *data;
223         int ret;
224 
225         int expected_rows;
226         int expected_width;
227         char *comment;
228         char *expected;
229     };
230     struct item data[] = {
231         /*  0*/ { BARCODE_MSI_PLESSEY, -1, "1234567890", 0, 1, 127, "Verified manually against tec-it",
232                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001"
233                 },
234         /*  1*/ { BARCODE_MSI_PLESSEY, 1, "1234567890", 0, 1, 139, "Verified manually against tec-it",
235                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001"
236                 },
237         /*  2*/ { BARCODE_MSI_PLESSEY, 2, "1234567890", 0, 1, 151, "Verified manually against tec-it",
238                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001001001101001"
239                 },
240         /*  3*/ { BARCODE_MSI_PLESSEY, 3, "1234567890", 0, 1, 139, "",
241                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001"
242                 },
243         /*  4*/ { BARCODE_MSI_PLESSEY, 4, "1234567890", 0, 1, 151, "",
244                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001001001101001"
245                 },
246         /*  5*/ { BARCODE_MSI_PLESSEY, 5, "1234567890", 0, 1, 139, "",
247                     "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001001001001"
248                 },
249         /*  6*/ { BARCODE_MSI_PLESSEY, 6, "1234567890", 0, 1, 151, "",
250                    "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001001001001101101101001"
251                 },
252         /*  7*/ { BARCODE_MSI_PLESSEY, 3, "2211", 0, 1, 79, "Produces mod-11 '10' check digit; BWIPP (badmod11)",
253                     "1101001001101001001001101001001001001101001001001101001001001101001001001001001"
254                 },
255         /*  8*/ { BARCODE_MSI_PLESSEY, 4, "2211", 0, 1, 91, "BWIPP (badmod11)",
256                     "1101001001101001001001101001001001001101001001001101001001001101001001001001001001001001001"
257                 },
258         /*  9*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", 0, 1, 323, "",
259                     "11101110100011101000100010001000111010001000100010001110100010001110111010001000100010001110100011101000111010001000111011101000111011101110100010001000100011101110100010001110100011101000111011101110100011101000100011101110111010001110111010001110111011101110111011101110111010001000111010001000100010001110001000101110111"
260                 },
261         /* 10*/ { BARCODE_MSI_PLESSEY, 4, "999999999999999999", 0, 1, 247, "Max value (previously); #209 check buffer not overrun",
262                     "1101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001001001001001101001"
263                 },
264     };
265     int data_size = ARRAY_SIZE(data);
266     int i, length, ret;
267     struct zint_symbol *symbol;
268 
269     char escaped[1024];
270     char bwipp_buf[4096];
271     char bwipp_msg[1024];
272 
273     int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
274 
275     testStart("test_encode");
276 
277     for (i = 0; i < data_size; i++) {
278 
279         if (index != -1 && i != index) continue;
280 
281         symbol = ZBarcode_Create();
282         assert_nonnull(symbol, "Symbol not created\n");
283 
284         length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
285 
286         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
287         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
288 
289         if (generate) {
290             printf("        /*%3d*/ { %s, %d, \"%s\", %s, %d, %d, \"%s\",\n",
291                     i, testUtilBarcodeName(data[i].symbology), data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
292                     testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
293             testUtilModulesPrint(symbol, "                    ", "\n");
294             printf("                },\n");
295         } else {
296             if (ret < ZINT_ERROR) {
297                 int width, row;
298 
299                 assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
300                 assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
301 
302                 ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
303                 assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
304 
305                 if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
306                     ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf));
307                     assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
308 
309                     ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
310                     assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n  actual: %s\nexpected: %s\n",
311                                    i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
312                 }
313             }
314         }
315 
316         ZBarcode_Delete(symbol);
317     }
318 
319     testFinish();
320 }
321 
main(int argc,char * argv[])322 int main(int argc, char *argv[]) {
323 
324     testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
325         { "test_large", test_large, 1, 0, 1 },
326         { "test_hrt", test_hrt, 1, 0, 1 },
327         { "test_input", test_input, 1, 0, 1 },
328         { "test_encode", test_encode, 1, 1, 1 },
329     };
330 
331     testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
332 
333     testReport();
334 
335     return 0;
336 }
337