1 /*
2     libzint - the open source barcode library
3     Copyright (C) 2019 - 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 option_1;
38         int option_2;
39         char *pattern;
40         int length;
41         int ret;
42         int expected_rows;
43         int expected_width;
44     };
45     // é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
46     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
47     struct item data[] = {
48         /*  0*/ { -1, -1, "A", 2666, 0, 44, 728 },
49         /*  1*/ { -1, -1, "A", 2725, 0, 44, 739 },
50         /*  2*/ { -1, -1, "A", 2726, 0, 44, 739 }, // 4.2.1 c.3 says max 2725 but actually 44 * 62 - 2 == 2726 as mentioned later in 4.8.1
51         /*  3*/ { -1, -1, "A", 2727, ZINT_ERROR_TOO_LONG, -1, -1 },
52         /*  4*/ { -1, -1, "A", ZINT_MAX_DATA_LEN, ZINT_ERROR_TOO_LONG, -1, -1 },
53         /*  5*/ { -1, -1, "12", 2726 * 2, 0, 44, 739 },
54         /*  6*/ { -1, -1, "12", 2726 * 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
55         /*  7*/ { -1, -1, "\351", 2726 / 2, 0, 44, 739 },
56         /*  8*/ { -1, -1, "\351", 2726 / 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
57         /*  9*/ { 1, -1, "A", 60, 0, 1, 695 }, // CODE128 60 max
58         /* 10*/ { 1, -1, "A", 61, ZINT_ERROR_TOO_LONG, -1, -1 },
59         /* 11*/ { 2, -1, "A", 122, 0, 2, 739 },
60         /* 12*/ { 2, 10, "A", 122, 0, 2, 739 }, // Cols 10 -> 67
61         /* 13*/ { 2, 67, "A", 122, 0, 2, 739 },
62         /* 14*/ { 2, -1, "A", 123, ZINT_ERROR_TOO_LONG, -1, -1 },
63         /* 15*/ { 2, -1, "A", 63 * 2, ZINT_ERROR_TOO_LONG, -1, -1 }, // Triggers initial testColumns > 62
64         /* 16*/ { 2, -1, "A", 2726 * 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
65         /* 17*/ { 2, 9, "A", 2726 * 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
66         /* 18*/ { 3, -1, "A", 184, 0, 3, 739 },
67         /* 19*/ { 3, -1, "A", 185, ZINT_ERROR_TOO_LONG, -1, -1 },
68         /* 20*/ { 10, -1, "A", 618, 0, 10, 739 },
69         /* 21*/ { 10, -1, "A", 619, ZINT_ERROR_TOO_LONG, -1, -1 },
70         /* 22*/ { 20, -1, "A", 1238, 0, 20, 739 },
71         /* 23*/ { 20, -1, "A", 1239, ZINT_ERROR_TOO_LONG, -1, -1 },
72         /* 24*/ { 30, -1, "A", 1858, 0, 30, 739 },
73         /* 25*/ { 30, -1, "A", 1859, ZINT_ERROR_TOO_LONG, -1, -1 },
74         /* 26*/ { 40, -1, "A", 2478, 0, 40, 739 },
75         /* 27*/ { 40, -1, "A", 2479, ZINT_ERROR_TOO_LONG, -1, -1 },
76         /* 28*/ { 43, -1, "A", 2664, 0, 43, 739 },
77         /* 29*/ { 43, -1, "A", 2665, ZINT_ERROR_TOO_LONG, -1, -1 },
78         /* 30*/ { 44, -1, "A", 2726, 0, 44, 739 },
79         /* 31*/ { 44, -1, "A", 2727, ZINT_ERROR_TOO_LONG, -1, -1 },
80         /* 32*/ { 44, 60, "A", 2726, 0, 44, 739 }, // Cols 60 -> 67
81         /* 33*/ { 44, 67, "A", 2726, 0, 44, 739 },
82     };
83     int data_size = ARRAY_SIZE(data);
84     int i, length, ret;
85     struct zint_symbol *symbol;
86 
87     char data_buf[ZINT_MAX_DATA_LEN + 2];
88 
89     testStart("test_large");
90 
91     for (i = 0; i < data_size; i++) {
92 
93         if (index != -1 && i != index) continue;
94 
95         symbol = ZBarcode_Create();
96         assert_nonnull(symbol, "Symbol not created\n");
97 
98         testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
99         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));
100 
101         length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
102 
103         ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
104         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
105 
106         if (ret < ZINT_ERROR) {
107             assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
108             assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
109         }
110 
111         ZBarcode_Delete(symbol);
112     }
113 
114     testFinish();
115 }
116 
test_options(int index,int debug)117 static void test_options(int index, int debug) {
118 
119     struct item {
120         int input_mode;
121         int option_1;
122         int option_2;
123         char *data;
124         int ret;
125         int expected_rows;
126         int expected_width;
127         char *comment;
128     };
129     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
130     struct item data[] = {
131         /*  0*/ { UNICODE_MODE, 1, -1, "é", 0, 1, 57, "CODE128" },
132         /*  1*/ { UNICODE_MODE, -1, -1, "A", 0, 2, 101, "Defaults" },
133         /*  2*/ { UNICODE_MODE, 0, -1, "A", 0, 2, 101, "0 rows same as -1" },
134         /*  3*/ { UNICODE_MODE, 2, -1, "A", 0, 2, 101, "Rows 2, columns default" },
135         /*  4*/ { UNICODE_MODE, 3, -1, "A", 0, 3, 101, "Rows 3" },
136         /*  5*/ { UNICODE_MODE, 43, -1, "A", 0, 43, 101, "Rows 43" },
137         /*  6*/ { UNICODE_MODE, 44, -1, "A", 0, 44, 101, "Max rows" },
138         /*  7*/ { UNICODE_MODE, 45, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "" },
139         /*  8*/ { UNICODE_MODE, -1, -1, "abcdefg", 0, 3, 101, "" },
140         /*  9*/ { UNICODE_MODE, 2, -1, "abcdefg", 0, 2, 112, "Rows given so columns expanded" },
141         /* 10*/ { UNICODE_MODE, 3, -1, "abcdefg", 0, 3, 101, "" },
142         /* 11*/ { UNICODE_MODE, -1, 8, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "Min columns 9 (4 data)" },
143         /* 12*/ { UNICODE_MODE, -1, 9, "A", 0, 2, 101, "Min columns 9 (4 data)" },
144         /* 13*/ { UNICODE_MODE, -1, 10, "A", 0, 2, 112, "Columns 10" },
145         /* 14*/ { UNICODE_MODE, -1, 66, "A", 0, 2, 728, "Columns 66" },
146         /* 15*/ { UNICODE_MODE, -1, 67, "A", 0, 2, 739, "Max columns 67 (62 data)" },
147         /* 16*/ { UNICODE_MODE, -1, 68, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "" },
148         /* 17*/ { UNICODE_MODE, 2, 9, "A", 0, 2, 101, "Rows and columns defaults given" },
149         /* 18*/ { UNICODE_MODE, 2, 10, "A", 0, 2, 112, "Rows and columns given" },
150         /* 19*/ { UNICODE_MODE, 3, 11, "A", 0, 3, 123, "" },
151         /* 20*/ { UNICODE_MODE, 43, 66, "A", 0, 43, 728, "" },
152         /* 21*/ { UNICODE_MODE, 44, 67, "A", 0, 44, 739, "Max rows, max columns" },
153         /* 22*/ { GS1_MODE, -1, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "GS1 not supported" },
154         /* 23*/ { GS1_MODE, 1, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "Check for CODE128" },
155     };
156     int data_size = ARRAY_SIZE(data);
157     int i, length, ret;
158     struct zint_symbol *symbol;
159 
160     testStart("test_options");
161 
162     for (i = 0; i < data_size; i++) {
163 
164         if (index != -1 && i != index) continue;
165 
166         symbol = ZBarcode_Create();
167         assert_nonnull(symbol, "Symbol not created\n");
168 
169         length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
170 
171         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
172         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
173 
174         if (ret < ZINT_ERROR) {
175             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);
176             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);
177         }
178 
179         ZBarcode_Delete(symbol);
180     }
181 
182     testFinish();
183 }
184 
test_reader_init(int index,int generate,int debug)185 static void test_reader_init(int index, int generate, int debug) {
186 
187     struct item {
188         int symbology;
189         int input_mode;
190         int output_options;
191         char *data;
192         int ret;
193         int expected_rows;
194         int expected_width;
195         char *expected;
196         char *comment;
197     };
198     struct item data[] = {
199         /*  0*/ { BARCODE_CODABLOCKF, UNICODE_MODE, READER_INIT, "1234", 0, 2, 101, "67 64 40 60 63 0C 22 2B 6A 67 64 0B 63 64 3A 1C 29 6A", "CodeB FNC3 CodeC 12 34 / CodeB Pads" },
200         /*  1*/ { BARCODE_CODABLOCKF, UNICODE_MODE, READER_INIT, "\001\002", 0, 2, 101, "67 62 40 60 41 42 63 32 6A 67 64 0B 63 64 45 42 0F 6A", "FNC3 SOH STX / CodeB Pads" },
201         /*  2*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, READER_INIT, "123456", 0, 3, 101, "67 64 41 60 0B 11 12 22 6A 67 63 2B 22 38 64 2A 1B 6A 67 64 0C 63 64 2B 2F 52 6A", "CodeB FNC3 + 1 2 / CodeC 34 56 CodeB J" },
202     };
203     int data_size = ARRAY_SIZE(data);
204     int i, length, ret;
205     struct zint_symbol *symbol;
206 
207     char escaped[1024];
208 
209     testStart("test_reader_init");
210 
211     for (i = 0; i < data_size; i++) {
212 
213         if (index != -1 && i != index) continue;
214 
215         symbol = ZBarcode_Create();
216         assert_nonnull(symbol, "Symbol not created\n");
217 
218         symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
219 
220         length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug);
221 
222         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
223         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
224 
225         if (generate) {
226             printf("        /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n",
227                     i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options),
228                     testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
229                     testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment);
230         } else {
231             if (ret < ZINT_ERROR) {
232                 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);
233                 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);
234                 assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
235             }
236         }
237 
238         ZBarcode_Delete(symbol);
239     }
240 
241     testFinish();
242 }
243 
test_input(int index,int generate,int debug)244 static void test_input(int index, int generate, int debug) {
245 
246     struct item {
247         int symbology;
248         int input_mode;
249         int option_2;
250         char *data;
251         int length;
252         int ret;
253         int expected_rows;
254         int expected_width;
255         char *expected;
256         char *comment;
257     };
258     // NUL U+0000, CodeA-only
259     // US U+001F (\037, 31), CodeA-only
260     // a U+0061 (\141, 97), CodeB-only
261     // DEL U+007F (\177, 127), CodeB-only
262     // PAD U+0080 (\200, 128), UTF-8 C280 (\302\200), CodeA-only extended ASCII, not in ISO 8859-1
263     // APC U+009F (\237, 159), UTF-8 C29F, CodeA-only extended ASCII, not in ISO 8859-1
264     // NBSP U+00A0 (\240, 160), UTF-8 C2A0, CodeA and CodeB extended ASCII
265     // ß U+00DF (\337, 223), UTF-8 C39F, CodeA and CodeB extended ASCII
266     // à U+00E0 (\340, 224), UTF-8 C3A0, CodeB-only extended ASCII
267     // á U+00E1 (\341, 225), UTF-8 C3A1, CodeB-only extended ASCII
268     // é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
269     // ñ U+00F1 (\361, 241), UTF-8 C3B1, CodeB-only extended ASCII
270     // ÿ U+00FF (\377, 255), UTF-8 C3BF, CodeB-only extended ASCII
271     struct item data[] = {
272         /*  0*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "A", -1, 0, 2, 101, "67 64 40 21 63 64 63 42 6A 67 64 0B 63 64 2B 40 4F 6A", "Fillings 5" },
273         /*  1*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAA", -1, 0, 2, 101, "67 64 40 21 21 21 63 55 6A 67 64 0B 63 64 0E 57 48 6A", "Fillings 3" },
274         /*  2*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 63 64 1A 0E 03 6A", "Fillings 2" },
275         /*  3*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 21 63 1D 30 14 6A", "Fillings 1" },
276         /*  4*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 21 21 35 5D 2B 6A", "Fillings 0" },
277         /*  5*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234", -1, 0, 2, 101, "67 63 00 0C 22 64 63 1A 6A 67 64 0B 63 64 3A 1C 29 6A", "Fillings 4" },
278         /*  6*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "12345", -1, 0, 2, 101, "67 63 00 0C 22 64 15 49 6A 67 64 0B 63 64 41 44 07 6A", "Fillings 2 (not counting CodeB at end of 1st line)" },
279         /*  7*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "123456", -1, 0, 2, 101, "67 63 00 0C 22 38 64 12 6A 67 64 0B 63 64 2D 50 52 6A", "Fillings 3" },
280         /*  8*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234567", -1, 0, 2, 101, "67 63 00 0C 22 38 64 12 6A 67 64 0B 17 63 16 02 5B 6A", "Fillings 1 (not counting CodeB at end of 1st line)" },
281         /*  9*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "12345678", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 63 64 08 1C 64 6A", "Fillings 2" },
282         /* 10*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "123456789", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 19 63 25 4C 65 6A", "Fillings 1" },
283         /* 11*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234567890", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 19 10 41 38 62 6A", "Fillings 0" },
284         /* 12*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "A123ñ", -1, 0, 2, 101, "67 64 40 21 11 12 13 54 6A 67 64 0B 64 51 42 28 50 6A", "K1/K2 example in Annex F" },
285         /* 13*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aß", -1, 0, 2, 101, "67 64 40 41 64 3F 63 54 6A 67 64 0B 63 64 5B 1D 06 6A", "CodeB a FNC4 ß fits 1st line" },
286         /* 14*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037ß", -1, 0, 2, 101, "67 62 40 5F 65 3F 63 49 6A 67 64 0B 63 64 0F 1D 26 6A", "CodeA US FNC4 ß fits 1st line" },
287         /* 15*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaß", -1, 0, 2, 101, "67 64 40 41 41 64 3F 10 6A 67 64 0B 63 64 4E 5B 04 6A", "CodeB a a FNC4 ß fits 1st line" },
288         /* 16*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037ß", -1, 0, 2, 101, "67 62 40 5F 5F 65 3F 17 6A 67 64 0B 63 64 34 0F 24 6A", "CodeA US US FNC4 ß fits 1st line" },
289         /* 17*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaaß", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 64 0B 64 3F 4C 4E 50 6A", "CodeB a (3) / CodeB FNC4 ß fully on next line" },
290         /* 18*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037\037ß", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 64 0B 64 3F 0E 34 1A 6A", "CodeA US (3) / CodeB FNC4 ß fully on next line" },
291         /* 19*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aà", -1, 0, 2, 101, "67 64 40 41 64 40 63 59 6A 67 64 0B 63 64 5D 1E 16 6A", "CodeB a FNC4 à fits 1st line" },
292         /* 20*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037à", -1, 0, 2, 101, "67 62 40 5F 65 62 40 26 6A 67 64 0B 63 64 1B 1E 01 6A", "CodeA US FNC4 Shift à fits 1st line" },
293         /* 21*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037àa", -1, 0, 2, 101, "67 62 40 5F 64 64 40 2C 6A 67 64 0B 41 63 52 4A 16 6A", "CodeA US LatchB FNC4 à fits 1st line / Code B a" },
294         /* 22*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaà", -1, 0, 2, 101, "67 64 40 41 41 64 40 16 6A 67 64 0B 63 64 51 5D 1F 6A", "CodeB a a FNC4 à fits 1st line" },
295         /* 23*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037à", -1, 0, 2, 101, "67 62 40 5F 5F 63 64 1D 6A 67 64 0B 64 40 37 1B 55 6A", "CodeA US US / Code B FNC4 à fully on next line" },
296         /* 24*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaaà", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 64 0B 64 40 50 51 13 6A", "CodeB a (3) / Code B FNC4 à fully on next line" },
297         /* 25*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037\037à", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 64 0B 64 40 1C 37 0F 6A", "CodeA US (3) / CodeB FNC4 à fully on next line" },
298         /* 26*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\200", -1, 0, 2, 101, "67 62 40 5F 65 40 63 4E 6A 67 64 0B 63 64 5D 0A 05 6A", "CodeA US FNC4 PAD fits 1st line" },
299         /* 27*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\200", -1, 0, 2, 101, "67 64 40 41 64 62 40 31 6A 67 64 0B 63 64 49 0A 08 6A", "CodeB a FNC4 Shift PAD fits 1st line" },
300         /* 28*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\200\037", -1, 0, 2, 101, "67 64 40 41 65 65 40 44 6A 67 62 0B 5F 63 10 12 3E 6A", "CodeB a LatchA FNC4 PAD fits 1st line / CodeA US" },
301         /* 29*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\037\200", -1, 0, 2, 101, "67 62 40 5F 5F 65 40 1D 6A 67 64 0B 63 64 0F 5D 0A 6A", "CodeA US US FNC4 PAD fits 1st line" },
302         /* 30*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\141\200", -1, 0, 2, 101, "67 64 40 41 41 63 64 1B 6A 67 62 0B 65 40 33 49 21 6A", "CodeB a a / CodeA FNC4 PAD fully on next line" },
303         /* 31*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\037\037\200", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 62 0B 65 40 4A 0F 06 6A", "CodeA US (3) / CodeA FNC4 PAD fully on next line" },
304         /* 32*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\141\141\200", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 62 0B 65 40 28 33 34 6A", "CodeB a (3) / CodeA FNC4 PAD fully on next line" },
305         /* 33*/ { BARCODE_CODABLOCKF, DATA_MODE, 10, "\200\240\237\340\337\341\377", -1, 0, 4, 112, "(40) 67 62 42 65 40 65 00 63 1E 6A 67 62 0B 65 5F 64 64 40 55 6A 67 64 0C 64 3F 64 41 63", "" },
306         /* 34*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\000a\037\177}12", 7, 0, 3, 101, "67 62 41 40 62 41 5F 3B 6A 67 64 0B 5F 5D 11 12 2D 6A 67 64 0C 63 64 40 05 26 6A", "" },
307         /* 35*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "abcdéf", -1, 0, 3, 101, "67 64 41 41 42 43 44 5D 6A 67 64 0B 64 49 46 63 0A 6A 67 64 0C 63 64 4F 26 02 6A", "" },
308         /* 36*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "a12é\000", 6, 0, 3, 101, "67 64 41 41 11 12 63 2C 6A 67 64 0B 64 49 62 40 2B 6A 67 64 0C 63 64 33 34 31 6A", "" },
309         /* 37*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 11, "1234\001", -1, 0, 2, 123, "67 63 00 0C 22 65 41 63 64 54 6A 67 64 0B 63 64 63 64 3F 20 24 6A", "" },
310         /* 38*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, "A99912345/$$52001510X3", -1, 0, 6, 101, "(54) 67 64 44 0B 21 19 19 3A 6A 67 63 2B 5B 17 2D 64 24 6A 67 64 0C 0F 04 04 15 16 6A 67", "" },
311     };
312     int data_size = ARRAY_SIZE(data);
313     int i, length, ret;
314     struct zint_symbol *symbol;
315 
316     char escaped[1024];
317 
318     testStart("test_input");
319 
320     for (i = 0; i < data_size; i++) {
321 
322         if (index != -1 && i != index) continue;
323 
324         symbol = ZBarcode_Create();
325         assert_nonnull(symbol, "Symbol not created\n");
326 
327         symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
328 
329         length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
330 
331         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
332         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
333 
334         if (generate) {
335             printf("        /*%3d*/ { %s, %s, %d, \"%s\", %d, %s, %d, %d, \"%s\", \"%s\" },\n",
336                     i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].option_2,
337                     testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length,
338                     testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment);
339         } else {
340             if (ret < ZINT_ERROR) {
341                 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);
342                 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);
343                 assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
344             }
345         }
346 
347         ZBarcode_Delete(symbol);
348     }
349 
350     testFinish();
351 }
352 
test_encode(int index,int generate,int debug)353 static void test_encode(int index, int generate, int debug) {
354 
355     struct item {
356         int symbology;
357         int option_1;
358         int option_2;
359         char *data;
360         int ret;
361 
362         int expected_rows;
363         int expected_width;
364         int bwipp_cmp;
365         char *comment;
366         char *expected;
367     };
368     struct item data[] = {
369         /*  0*/ { BARCODE_CODABLOCKF, 1, -1, "AIM", 0, 1, 68, 1, "Same as CODE128 (not supported by BWIPP)",
370                     "11010010000101000110001100010001010111011000101110110001100011101011"
371                 },
372         /*  1*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against tec-it",
373                     "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011"
374                     "11010000100101111011101100010010010100011000101000110001010001100010111011110100100111101100011101011"
375                     "11010000100101111011101011001110010111011110101111011101100001010011011101110111100101001100011101011"
376                 },
377         /*  2*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against tec-it",
378                     "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011"
379                     "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
380                     "11010000100101111011101011001110010100011000101000110001110110010010010110000111000101101100011101011"
381                 },
382         /*  3*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against tec-it",
383                     "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011"
384                     "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
385                     "11010000100101111011101011001110010100011000101000110001010001100010111011110100111101001100011101011"
386                     "11010000100101111011101001101110010111011110101111011101110101100011101100100110010111001100011101011"
387                 },
388         /*  4*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against tec-it",
389                     "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011"
390                     "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
391                     "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
392                     "11010000100101111011101001101110010100011000101000110001011110100010111011000100110000101100011101011"
393                 },
394         /*  5*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against tec-it",
395                     "11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011"
396                     "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
397                     "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
398                     "11010000100101111011101001101110010100011000101000110001010001100010111011110111101001001100011101011"
399                     "11010000100101111011101001100111010111011110101111011101000110001010111101000110001010001100011101011"
400                 },
401         /*  6*/ { BARCODE_CODABLOCKF, -1, 14, "AAAAAAAAAAAAAAA", 0, 2, 156, 1, "Rows 2, columns 14 (9 data); verified manually against tec-it",
402                     "110100001001011110111010100001100101000110001010001100010100011000101000110001010001100010100011000101000110001010001100010100011000110001000101100011101011"
403                     "110100001001011110111011000100100101000110001010001100010100011000101000110001010001100010100011000101110111101110111101011011000110111000101101100011101011"
404                 },
405         /*  7*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against tec-it",
406                     "11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011"
407                     "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
408                     "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
409                     "11010000100101111011101001101110010100011000101000110001010001100010100011000111101011101100011101011"
410                     "11010000100101111011101001100111010111011110101111011101011100011010001100010100011101101100011101011"
411                 },
412         /*  8*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAAAAAAAAAAA", 0, 6, 112, 1, "Defaults to rows 6, columns 10 (5 data); verified manually against tec-it",
413                     "1101000010010111101110100001001101010001100010100011000101000110001010001100010100011000110110001101100011101011"
414                     "1101000010010111101110110001001001010001100010100011000101000110001010001100010100011000110010011101100011101011"
415                     "1101000010010111101110101100111001010001100010100011000101000110001010001100010100011000110011101001100011101011"
416                     "1101000010010111101110100110111001010001100010100011000101000110001010001100010100011000111010011001100011101011"
417                     "1101000010010111101110100110011101010001100010100011000101000110001010001100010100011000111001001101100011101011"
418                     "1101000010010111101110101110011001011101111010111101110101110111101110100011010100001100110001010001100011101011"
419                 },
420         /*  9*/ { BARCODE_CODABLOCKF, 4, -1, "CODABLOCK F 34567890123456789010040digit", 0, 4, 145, 1, "AIM ISS-X-24 Figure 1",
421                     "1101000010010111101110100100001101000100011010001110110101100010001010001100010001011000100011011101000111011010001000110110110011001100011101011"
422                     "1101000010010111101110110001001001011000111011011001100100011000101101100110010111011110100010110001110001011011000010100101100111001100011101011"
423                     "1101000010010111011110100011011101101111011010110011100100010110001110001011011000010100110111101101100100010010010001100100011000101100011101011"
424                     "1101000010010111101110100110111001001110110010000100110100001101001001101000010000110100100111101001101110111010111000110110010000101100011101011"
425                 },
426         /* 10*/ { BARCODE_CODABLOCKF, 3, -1, "CODABLOCK F Symbology", 0, 3, 145, 1, "AIM ISS-X-24 Figure on front page",
427                     "1101000010010111101110100101100001000100011010001110110101100010001010001100010001011000100011011101000111011010001000110111010111101100011101011"
428                     "1101000010010111101110110001001001011000111011011001100100011000101101100110011011101000110110111101111011101010010000110100100111101100011101011"
429                     "1101000010010111101110101100111001000111101011001010000100011110101001101000011011011110101110111101000011001011011101110101001111001100011101011"
430                 },
431         /* 11*/ { BARCODE_HIBC_BLOCKF, 3, -1, "A123BJC5D6E71", 0, 3, 123, 0, "Verified manually against tec-it; differs from BWIPP (columns=6) which uses Code C for final 71 (same no. of codewords)",
432                     "110100001001011110111010010110000110001001001010001100010011100110110011100101100101110010001011000100100001101100011101011"
433                     "110100001001011110111011000100100101101110001000100011011011100100101100010001100111010010001101000111001001101100011101011"
434                     "110100001001011110111010110011100111011011101001110011011010001000101110111101011100011011001110100100100110001100011101011"
435                 },
436         /* 12*/ { BARCODE_HIBC_BLOCKF, -1, -1, "$$52001510X3G", 0, 4, 101, 1, "tec-it differs as adds unnecessary Code C at end of 1st line",
437                     "11010000100101111011101001000011011000100100100100011001001000110011011100100101110011001100011101011"
438                     "11010000100101110111101011000111011001001110110011011001101110100010111101110100001100101100011101011"
439                     "11010000100101111011101011001110010011101100111000101101100101110011010001000100100011001100011101011"
440                     "11010000100101111011101001101110010110001000101110111101101000111011000110110100011010001100011101011"
441                 },
442     };
443     int data_size = ARRAY_SIZE(data);
444     int i, length, ret;
445     struct zint_symbol *symbol;
446 
447     char escaped[1024];
448     char bwipp_buf[8192];
449     char bwipp_msg[1024];
450 
451     int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
452 
453     testStart("test_encode");
454 
455     for (i = 0; i < data_size; i++) {
456 
457         if (index != -1 && i != index) continue;
458 
459         symbol = ZBarcode_Create();
460         assert_nonnull(symbol, "Symbol not created\n");
461 
462         length = testUtilSetSymbol(symbol, data[i].symbology, UNICODE_MODE, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
463 
464         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
465         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
466 
467         if (generate) {
468             printf("        /*%3d*/ { %s, %d, %d, \"%s\", %s, %d, %d, %d, \"%s\",\n",
469                     i, testUtilBarcodeName(data[i].symbology), data[i].option_1, data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
470                     testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
471             testUtilModulesPrint(symbol, "                    ", "\n");
472             printf("                },\n");
473         } else {
474             if (ret < ZINT_ERROR) {
475                 int width, row;
476 
477                 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);
478                 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);
479 
480                 ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
481                 assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
482 
483                 if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) {
484                     if (!data[i].bwipp_cmp) {
485                         if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
486                     } else {
487                         ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf));
488                         assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
489 
490                         ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
491                         assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n  actual: %s\nexpected: %s\n",
492                                        i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
493                     }
494                 }
495             }
496         }
497 
498         ZBarcode_Delete(symbol);
499     }
500 
501     testFinish();
502 }
503 
504 // #181 Christian Hartlage OSS-Fuzz
test_fuzz(int index,int debug)505 static void test_fuzz(int index, int debug) {
506 
507     struct item {
508         char *data;
509         int length;
510         int ret;
511     };
512     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
513     struct item data[] = {
514         /*  0*/ { "\034\034I", 3, 0 },
515     };
516     int data_size = ARRAY_SIZE(data);
517     int i, length, ret;
518     struct zint_symbol *symbol;
519 
520     testStart("test_fuzz");
521 
522     for (i = 0; i < data_size; i++) {
523 
524         if (index != -1 && i != index) continue;
525 
526         symbol = ZBarcode_Create();
527         assert_nonnull(symbol, "Symbol not created\n");
528 
529         length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
530 
531         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
532         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
533 
534         ZBarcode_Delete(symbol);
535     }
536 
537     testFinish();
538 }
539 
main(int argc,char * argv[])540 int main(int argc, char *argv[]) {
541 
542     testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
543         { "test_large", test_large, 1, 0, 1 },
544         { "test_options", test_options, 1, 0, 1 },
545         { "test_reader_init", test_reader_init, 1, 1, 1 },
546         { "test_input", test_input, 1, 1, 1 },
547         { "test_encode", test_encode, 1, 1, 1 },
548         { "test_fuzz", test_fuzz, 1, 0, 1 },
549     };
550 
551     testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
552 
553     testReport();
554 
555     return 0;
556 }
557