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 #include <fcntl.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36 
test_checks(int index,int debug)37 static void test_checks(int index, int debug) {
38 
39     struct item {
40         int symbology;
41         int option_1;
42         char *data;
43         int length;
44         int input_mode;
45         int eci;
46         float dot_size;
47         int warn_level;
48         int ret;
49 
50         char *expected;
51         int expected_symbology;
52     };
53     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
54     struct item data[] = {
55         /*  0*/ { BARCODE_CODE128, -1, "1234", -1, -1, 3, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", -1 },
56         /*  1*/ { BARCODE_CODE128, -1, "1234", -1, -1, 0, -1, -1, 0, "", -1 },
57         /*  2*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 3, -1, -1, 0, "", -1 },
58         /*  3*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 999999 + 1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI mode", -1 },
59         /*  4*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 20.1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size", -1 },
60         /*  5*/ { BARCODE_CODE128, -1, "1234", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 220: Selected symbology does not support GS1 mode", -1 },
61         /*  6*/ { BARCODE_GS1_128, -1, "[21]12\0004", 8, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 262: NUL characters not permitted in GS1 mode", -1 },
62         /*  7*/ { BARCODE_GS1_128, -1, "[21]12é4", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1", -1 },
63         /*  8*/ { BARCODE_GS1_128, -1, "[21]12\0074", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 251: Control characters are not supported by GS1", -1 },
64         /*  9*/ { BARCODE_GS1_128, -1, "[21]1234", -1, GS1_MODE, -1, -1, -1, 0, "", -1 },
65         /* 10*/ { 0, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 },
66         /* 11*/ { 0, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 },
67         /* 12*/ { 0, -1, "1", -1, -1, 1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, // Not supporting beats invalid ECI
68         /* 13*/ { 0, -1, "1", -1, -1, 1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 },
69         /* 14*/ { 0, -1, "1", -1, -1, -1, 0.009, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size", BARCODE_CODE128 },
70         /* 15*/ { 0, -1, "1", -1, -1, -1, 0.009, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 },
71         /* 16*/ { 0, -1, "1", -1, -1, 1, 0.009, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, // Invalid dot size no longer beats invalid ECI
72         /* 17*/ { 0, -1, "1", -1, -1, -1, 0.009, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 },
73         /* 18*/ { 5, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_C25STANDARD },
74         /* 19*/ { 5, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_C25STANDARD },
75         /* 20*/ { 10, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_EANX },
76         /* 21*/ { 10, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_EANX },
77         /* 22*/ { 11, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_EANX },
78         /* 23*/ { 11, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_EANX },
79         /* 24*/ { 12, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_EANX },
80         /* 25*/ { 12, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_EANX },
81         /* 26*/ { 15, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_EANX },
82         /* 27*/ { 15, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_EANX },
83         /* 28*/ { 17, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_UPCA },
84         /* 29*/ { 17, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA },
85         /* 30*/ { 19, -1, "1", -1, -1, -1, -1, -1, ZINT_ERROR_TOO_LONG, "Error 362: Input too short (3 character minimum)", BARCODE_CODABAR },
86         /* 31*/ { 19, -1, "A1B", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 207: Codabar 18 not supported", BARCODE_CODABAR },
87         /* 32*/ { 19, -1, "A1B", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 207: Codabar 18 not supported", -1 },
88         /* 33*/ { 26, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_UPCA },
89         /* 34*/ { 26, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA },
90         /* 35*/ { 27, -1, "1", -1, -1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 208: UPCD1 not supported", 27 },
91         /* 36*/ { 33, -1, "1", -1, -1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 },
92         /* 37*/ { 33, -1, "[10]23", -1, -1, -1, -1, -1, 0, "", BARCODE_GS1_128 },
93         /* 38*/ { 33, -1, "[10]23", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 },
94         /* 39*/ { 36, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_UPCA },
95         /* 40*/ { 36, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA },
96         /* 41*/ { 39, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_UPCE },
97         /* 42*/ { 39, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCE },
98         /* 43*/ { 41, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_NONCOMPLIANT, "Warning 479: Input length is not standard (5, 9 or 11 characters)", BARCODE_POSTNET },
99         /* 44*/ { 41, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
100         /* 45*/ { 41, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
101         /* 46*/ { 42, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
102         /* 47*/ { 42, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
103         /* 48*/ { 43, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
104         /* 49*/ { 43, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
105         /* 50*/ { 44, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
106         /* 51*/ { 44, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
107         /* 52*/ { 45, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
108         /* 53*/ { 45, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
109         /* 54*/ { 46, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_PLESSEY },
110         /* 55*/ { 46, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_PLESSEY },
111         /* 56*/ { 48, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_NVE18 },
112         /* 57*/ { 48, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_NVE18 },
113         /* 58*/ { 54, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 210: General Parcel Code not supported", BARCODE_CODE128 },
114         /* 59*/ { 54, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 210: General Parcel Code not supported", -1 },
115         /* 60*/ { 59, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_CODE128 },
116         /* 61*/ { 59, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 },
117         /* 62*/ { 61, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_CODE128 },
118         /* 63*/ { 61, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 },
119         /* 64*/ { 62, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_CODE93 },
120         /* 65*/ { 62, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE93 },
121         /* 66*/ { 64, -1, "12345678", -1, -1, -1, -1, -1, 0, "", BARCODE_AUSPOST },
122         /* 67*/ { 64, -1, "12345678", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST },
123         /* 68*/ { 65, -1, "12345678", -1, -1, -1, -1, -1, 0, "", BARCODE_AUSPOST },
124         /* 69*/ { 65, -1, "12345678", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST },
125         /* 70*/ { 78, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_DBAR_OMN },
126         /* 71*/ { 78, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_DBAR_OMN },
127         /* 72*/ { 83, -1, "12345678901", -1, -1, -1, -1, -1, 0, "", BARCODE_PLANET },
128         /* 73*/ { 83, -1, "12345678901", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_PLANET },
129         /* 74*/ { 88, -1, "1", -1, -1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 },
130         /* 75*/ { 88, -1, "[10]12", -1, -1, -1, -1, -1, 0, "", BARCODE_GS1_128 },
131         /* 76*/ { 88, -1, "[10]12", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 },
132         /* 77*/ { 91, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 212: Symbology out of range", BARCODE_CODE128 },
133         /* 78*/ { 91, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 212: Symbology out of range", -1 },
134         /* 79*/ { 94, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 213: Symbology out of range", BARCODE_CODE128 },
135         /* 80*/ { 94, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 213: Symbology out of range", -1 },
136         /* 81*/ { 95, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 213: Symbology out of range", BARCODE_CODE128 },
137         /* 82*/ { 95, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 213: Symbology out of range", -1 },
138         /* 83*/ { 100, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_128 },
139         /* 84*/ { 100, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_128 },
140         /* 85*/ { 101, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_39 },
141         /* 86*/ { 101, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_39 },
142         /* 87*/ { 103, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_DM },
143         /* 88*/ { 103, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_DM },
144         /* 89*/ { 105, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_QR },
145         /* 90*/ { 105, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_QR },
146         /* 91*/ { 107, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_PDF },
147         /* 92*/ { 107, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_PDF },
148         /* 93*/ { 109, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_MICPDF },
149         /* 94*/ { 109, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_MICPDF },
150         /* 95*/ { 111, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_HIBC_BLOCKF },
151         /* 96*/ { 111, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_BLOCKF },
152         /* 97*/ { 113, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 214: Symbology out of range", BARCODE_CODE128 },
153         /* 98*/ { 113, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 214: Symbology out of range", -1 },
154         /* 99*/ { 114, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 214: Symbology out of range", BARCODE_CODE128 },
155         /*100*/ { 114, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 214: Symbology out of range", -1 },
156         /*101*/ { 117, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
157         /*102*/ { 117, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
158         /*103*/ { 118, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
159         /*104*/ { 118, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
160         /*105*/ { 119, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
161         /*106*/ { 119, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
162         /*107*/ { 120, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
163         /*108*/ { 120, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
164         /*109*/ { 122, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
165         /*110*/ { 122, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
166         /*111*/ { 123, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
167         /*112*/ { 123, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
168         /*113*/ { 124, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
169         /*114*/ { 124, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
170         /*115*/ { 125, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
171         /*116*/ { 125, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
172         /*117*/ { 126, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
173         /*118*/ { 126, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
174         /*119*/ { 127, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 215: Symbology out of range", BARCODE_CODE128 },
175         /*120*/ { 127, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 215: Symbology out of range", -1 },
176         /*121*/ { 146, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 216: Symbology out of range", BARCODE_CODE128 },
177         /*122*/ { 146, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 216: Symbology out of range", -1 },
178         /*123*/ { BARCODE_CODE128, -1, "\200", -1, UNICODE_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 245: Invalid UTF-8 in input data", -1 },
179         /*124*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, -1, -1, ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) position 14: Bad checksum '4', expected '1'", -1 },
180         /*125*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) position 14: Bad checksum '4', expected '1'", -1 },
181         /*126*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, 13, -1, -1, 0, "", -1 },
182         /*127*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 },
183         /*128*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 },
184         /*129*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 },
185         /*130*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 512: ECI ignored for GS1 mode", -1 },
186         /*131*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 }, // Warning in encoder overrides library warnings
187         /*132*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, -1, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) position 14: Bad checksum '4', expected '1'", -1 }, // But not errors
188         /*133*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, 13, -1, -1, 0, "", -1 },
189         /*134*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 },
190         /*135*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 },
191         /*136*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 503: Invalid error correction level - using default instead", -1 },
192         /*137*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Invalid error correction level - using default instead", -1 },
193         /*138*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, // ECI warning trumps all other warnings
194         /*139*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Invalid error correction level - using default instead", -1 }, // But not errors
195     };
196     int data_size = ARRAY_SIZE(data);
197     int i, length, ret;
198     struct zint_symbol *symbol;
199 
200     testStart("test_checks");
201 
202     for (i = 0; i < data_size; i++) {
203 
204         if (index != -1 && i != index) continue;
205 
206         symbol = ZBarcode_Create();
207         assert_nonnull(symbol, "Symbol not created\n");
208 
209         length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
210         if (data[i].dot_size != -1) {
211             symbol->dot_size = data[i].dot_size;
212         }
213         if (data[i].warn_level != -1) {
214             symbol->warn_level = data[i].warn_level;
215         }
216 
217         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
218         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt);
219 
220         ret = strcmp(symbol->errtxt, data[i].expected);
221         assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret);
222 
223         if (data[i].expected_symbology == -1) {
224             assert_equal(symbol->symbology, data[i].symbology, "i:%d symbol->symbology %d != original %d\n", i, symbol->symbology, data[i].symbology);
225         } else {
226             assert_equal(symbol->symbology, data[i].expected_symbology, "i:%d symbol->symbology %d != expected %d\n", i, symbol->symbology, data[i].expected_symbology);
227         }
228 
229         ZBarcode_Delete(symbol);
230     }
231 
232     testFinish();
233 }
234 
test_symbologies(void)235 static void test_symbologies(void) {
236     int i, ret;
237     struct zint_symbol symbol = {0};
238 
239     testStart("test_symbologies");
240 
241     for (i = -1; i < 148; i++) {
242         symbol.symbology = i;
243         ret = ZBarcode_Encode(&symbol, (unsigned char *) "1", 0);
244         assert_notequal(ret, ZINT_ERROR_ENCODING_PROBLEM, "i:%d Encoding problem (%s)\n", i, symbol.errtxt);
245     }
246 
247     testFinish();
248 }
249 
test_input_mode(int index,int debug)250 static void test_input_mode(int index, int debug) {
251 
252     struct item {
253         char *data;
254         int input_mode;
255         int ret;
256 
257         int expected_input_mode;
258     };
259     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
260     struct item data[] = {
261         /*  0*/ { "1234", DATA_MODE, 0, DATA_MODE },
262         /*  1*/ { "1234", DATA_MODE | ESCAPE_MODE, 0, DATA_MODE | ESCAPE_MODE },
263         /*  2*/ { "1234", UNICODE_MODE, 0, UNICODE_MODE },
264         /*  3*/ { "1234", UNICODE_MODE | ESCAPE_MODE, 0, UNICODE_MODE | ESCAPE_MODE },
265         /*  4*/ { "[01]12345678901231", GS1_MODE, 0, GS1_MODE },
266         /*  5*/ { "[01]12345678901231", GS1_MODE | ESCAPE_MODE, 0, GS1_MODE | ESCAPE_MODE },
267         /*  6*/ { "1234", 4 | ESCAPE_MODE, 0, DATA_MODE }, // Unknown mode reset to bare DATA_MODE
268         /*  7*/ { "1234", -1, 0, DATA_MODE },
269         /*  8*/ { "1234", DATA_MODE | 0x10, 0, DATA_MODE | 0x10 }, // Unknown flags kept (but ignored)
270         /*  9*/ { "1234", UNICODE_MODE | 0x10, 0, UNICODE_MODE | 0x10 },
271         /* 10*/ { "[01]12345678901231", GS1_MODE | 0x20, 0, GS1_MODE | 0x20 },
272     };
273     int data_size = ARRAY_SIZE(data);
274     int i, length, ret;
275     struct zint_symbol *symbol;
276 
277     testStart("test_input_mode");
278 
279     for (i = 0; i < data_size; i++) {
280 
281         if (index != -1 && i != index) continue;
282 
283         symbol = ZBarcode_Create();
284         assert_nonnull(symbol, "Symbol not created\n");
285 
286         length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
287 
288         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
289         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
290         assert_equal(symbol->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", i, symbol->input_mode, data[i].expected_input_mode);
291 
292         ZBarcode_Delete(symbol);
293     }
294 
295     testFinish();
296 }
297 
test_escape_char_process(int index,int generate,int debug)298 static void test_escape_char_process(int index, int generate, int debug) {
299 
300     struct item {
301         int symbology;
302         int input_mode;
303         int eci;
304         char *data;
305         int ret;
306         int expected_width;
307         char *expected;
308         int compare_previous;
309         char *comment;
310     };
311     struct item data[] = {
312         /*  0*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 26, "01 05 08 09 0A 0B 0C 0D E7 D8 7B 1F B6 4D 45 B6 45 7C EF DD 8C 4C 8D 1E D0 55 AD FE A8 52", 0, "" },
313         /*  1*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 101, "(45) 67 62 43 40 44 47 48 29 6A 67 62 0B 49 4A 4B 4C 18 6A 67 62 0C 4D 5B 5D 5E 62 6A 67", 0, "" },
314         /*  2*/ { BARCODE_CODE16K, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 70, "(20) 14 64 68 71 72 73 74 75 76 77 91 93 94 101 65 60 103 103 45 61", 0, "" },
315         /*  3*/ { BARCODE_DOTCODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 28, "65 40 44 47 48 49 4A 4B 4C 4D 5B 5D 5E 6E 41 3C", 0, "" },
316         /*  4*/ { BARCODE_GRIDMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "30 1A 00 02 01 61 00 48 28 16 0C 06 46 63 51 74 05 38 00", 0, "" },
317         /*  5*/ { BARCODE_HANXIN, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 23, "2F 80 10 72 09 28 B3 0D 6F F3 00 20 E8 F4 0A E0 00", 0, "" },
318         /*  6*/ { BARCODE_MAXICODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "(144) 04 3E 3E 00 04 07 08 09 0A 0B 03 3D 2C 24 19 1E 23 1B 18 0E 0C 0D 1E 21 3C 1E 3C 31", 0, "" },
319         /*  7*/ { BARCODE_PDF417, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 120, "(24) 16 901 0 23 655 318 98 18 461 639 893 122 129 92 900 900 872 438 359 646 522 773 831", 0, "" },
320         /*  8*/ { BARCODE_ULTRA, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 20, "(15) 257 0 4 7 8 9 10 11 12 13 27 29 30 129 92", 0, "" },
321         /*  9*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character in input data", 0, "" },
322         /* 10*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", 0, "" },
323         /* 11*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" },
324         /* 12*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" },
325         /* 13*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Corrupt escape character in input data", 0, "" },
326         /* 14*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xA01\\xFF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 0, "" },
327         /* 15*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00A01\\u00FF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" },
328         /* 16*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\xc3\\xbF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 0, "" },
329         /* 17*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00fF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" },
330         /* 18*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\xc3\\xbF", 0, 10, "EB 80 81 47 1E 45 FC 93", 0, "" },
331         /* 19*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u00fF", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" },
332         /* 20*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" },
333         /* 21*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uF", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" },
334         /* 22*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u0F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" },
335         /* 23*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\uFG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" },
336         /* 24*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" },
337         /* 25*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\u00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 211: Corrupt Unicode escape character in input data", 0, "" },
338         /* 26*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ufffe", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Reversed BOM" },
339         /* 27*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\ud800", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" },
340         /* 28*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\udfff", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" },
341         /* 29*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\xE2\\x82\\xAC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 0, "Zint manual 4.10 Ex1" },
342         /* 30*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 17, "\\u20AC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" },
343         /* 31*/ { BARCODE_DATAMATRIX, DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" },
344         /* 32*/ { BARCODE_DATAMATRIX, DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" },
345         /* 33*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" },
346     };
347     int data_size = ARRAY_SIZE(data);
348     int i, length, ret;
349     struct zint_symbol *symbol;
350 
351     char escaped[1024];
352     struct zint_symbol previous_symbol;
353     char *input_filename = "test_escape.txt";
354 
355     testStart("test_escape_char_process");
356 
357     for (i = 0; i < data_size; i++) {
358 
359         if (index != -1 && i != index) continue;
360         if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i);
361 
362         symbol = ZBarcode_Create();
363         assert_nonnull(symbol, "Symbol not created\n");
364 
365         symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
366 
367         length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
368 
369         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
370         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
371 
372         if (generate) {
373             printf("        /*%3d*/ { %s, %s, %d, \"%s\", %s, %d, \"%s\", %d, \"%s\" },\n",
374                     i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci,
375                     testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
376                     testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].compare_previous, data[i].comment);
377         } else {
378             assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
379 
380             if (ret < ZINT_ERROR) {
381                 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);
382                 if (index == -1 && data[i].compare_previous) {
383                     ret = testUtilSymbolCmp(symbol, &previous_symbol);
384                     assert_zero(ret, "i:%d testUtilSymbolCmp ret %d != 0\n", i, ret);
385                 }
386             }
387             memcpy(&previous_symbol, symbol, sizeof(previous_symbol));
388 
389             if (ret < 5) {
390                 // Test from input file
391                 FILE *fp;
392                 struct zint_symbol *symbol2;
393 
394                 fp = fopen(input_filename, "wb");
395                 assert_nonnull(fp, "i:%d fopen(%s) failed\n", i, input_filename);
396                 assert_notequal(fputs(data[i].data, fp), EOF, "i%d fputs(%s) failed == EOF (%d)\n", i, data[i].data, ferror(fp));
397                 assert_zero(fclose(fp), "i%d fclose() failed\n", i);
398 
399                 symbol2 = ZBarcode_Create();
400                 assert_nonnull(symbol, "Symbol2 not created\n");
401 
402                 symbol2->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
403 
404                 (void) testUtilSetSymbol(symbol2, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
405 
406                 ret = ZBarcode_Encode_File(symbol2, input_filename);
407                 assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_File ret %d != %d (%s)\n", i, ret, data[i].ret, symbol2->errtxt);
408                 assert_zero(strcmp(symbol2->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol2->errtxt, data[i].expected);
409 
410                 ret = testUtilSymbolCmp(symbol2, symbol);
411                 assert_zero(ret, "i:%d testUtilSymbolCmp symbol2 ret %d != 0\n", i, ret);
412 
413                 assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno));
414 
415                 ZBarcode_Delete(symbol2);
416             }
417         }
418 
419         ZBarcode_Delete(symbol);
420     }
421 
422     testFinish();
423 }
424 
test_cap(int index)425 static void test_cap(int index) {
426 
427     struct item {
428         int symbology;
429         unsigned cap_flag;
430         unsigned int expected;
431     };
432     // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
433     struct item data[] = {
434         /* 0*/ { BARCODE_CODE128, ZINT_CAP_HRT, ZINT_CAP_HRT },
435         /* 1*/ { BARCODE_CODE128, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_GS1, ZINT_CAP_HRT | ZINT_CAP_STACKABLE },
436         /* 2*/ { BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE, ZINT_CAP_ECI | ZINT_CAP_READER_INIT },
437         /* 3*/ { BARCODE_QRCODE, ZINT_CAP_HRT | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK, ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK },
438         /* 4*/ { BARCODE_EANX_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_ECI | ZINT_CAP_GS1, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_GS1 },
439         /* 5*/ { BARCODE_HANXIN, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK },
440         /* 6*/ { BARCODE_CODE11, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE, 0 },
441         /* 7*/ { BARCODE_POSTNET, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_COMPOSITE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK, 0 },
442         /* 8*/ { 0, 0, 0 },
443     };
444     int data_size = ARRAY_SIZE(data);
445     int i;
446     unsigned int ret;
447 
448     testStart("test_cap");
449 
450     for (i = 0; i < data_size; i++) {
451 
452         if (index != -1 && i != index) continue;
453 
454         ret = ZBarcode_Cap(data[i].symbology, data[i].cap_flag);
455         assert_equal(ret, data[i].expected, "i:%d ZBarcode_Cap(%s, 0x%X) 0x%X != 0x%X\n", i, testUtilBarcodeName(data[i].symbology), data[i].cap_flag, ret, data[i].expected);
456     }
457 
458     testFinish();
459 }
460 
test_encode_file_empty(void)461 static void test_encode_file_empty(void) {
462     int ret;
463     struct zint_symbol *symbol;
464     char filename[] = "in.bin";
465     FILE *fstream;
466 
467     testStart("test_encode_file_empty");
468 
469     symbol = ZBarcode_Create();
470     assert_nonnull(symbol, "Symbol not created\n");
471 
472     (void) remove(filename); // In case junk hanging around
473 
474     fstream = fopen(filename, "w+");
475     assert_nonnull(fstream, "fopen(%s) failed (%d)\n", filename, ferror(fstream));
476     ret = fclose(fstream);
477     assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret);
478 
479     ret = ZBarcode_Encode_File(symbol, filename);
480     assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File empty ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt);
481 
482     ret = remove(filename);
483     assert_zero(ret, "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno));
484 
485     ZBarcode_Delete(symbol);
486 
487     testFinish();
488 }
489 
test_encode_file_too_large(void)490 static void test_encode_file_too_large(void) {
491     char filename[] = "in.bin";
492     FILE *fstream;
493     int ret;
494     struct zint_symbol *symbol;
495     char buf[ZINT_MAX_DATA_LEN + 1] = {0};
496 
497     testStart("test_encode_file_too_large");
498 
499     symbol = ZBarcode_Create();
500     assert_nonnull(symbol, "Symbol not created\n");
501 
502     (void) remove(filename); // In case junk hanging around
503 
504     fstream = fopen(filename, "w+");
505     assert_nonnull(fstream, "fopen(%s) failed (%d)\n", filename, ferror(fstream));
506     ret = (int) fwrite(buf, 1, sizeof(buf), fstream);
507     assert_equal(ret, sizeof(buf), "fwrite return value: %d != %d\n", ret, (int)sizeof(buf));
508     ret = fclose(fstream);
509     assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret);
510 
511     ret = ZBarcode_Encode_File(symbol, filename);
512     assert_equal(ret, ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_File too large ret %d != ZINT_ERROR_TOO_LONG (%s)\n", ret, symbol->errtxt);
513 
514     ret = remove(filename);
515     assert_zero(ret, "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno));
516 
517     ZBarcode_Delete(symbol);
518 
519     testFinish();
520 }
521 
522 // #181 Nico Gunkel OSS-Fuzz
test_encode_file_unreadable(void)523 static void test_encode_file_unreadable(void) {
524 #ifndef _WIN32
525     int ret;
526     struct zint_symbol *symbol;
527     char filename[] = "in.bin";
528 
529     char buf[ZINT_MAX_DATA_LEN + 1] = {0};
530     int fd;
531 #endif
532 
533     testStart("test_encode_file_unreadable");
534 
535 #ifdef _WIN32
536     testSkip("Test not implemented on Windows");
537 #else
538 
539     symbol = ZBarcode_Create();
540     assert_nonnull(symbol, "Symbol not created\n");
541 
542     // Unreadable file
543     fd = creat(filename, S_IWUSR);
544     assert_notequal(fd, -1, "Unreadable input file (%s) not created == -1 (%d: %s)\n", filename, errno, strerror(errno));
545     ret = write(fd, buf, 1);
546     assert_equal(ret, 1, "Unreadable write ret %d != 1\n", ret);
547     ret = close(fd);
548     assert_zero(ret, "Unreadable close(%s) != 0(%d: %s)\n", filename, errno, strerror(errno));
549 
550     ret = ZBarcode_Encode_File(symbol, filename);
551     assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File unreadable ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt);
552 
553     ret = remove(filename);
554     assert_zero(ret, "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno));
555 
556     ZBarcode_Delete(symbol);
557 
558     testFinish();
559 #endif /* _WIN32 */
560 }
561 
562 // #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method
test_encode_file_directory(void)563 static void test_encode_file_directory(void) {
564     int ret;
565     struct zint_symbol *symbol;
566     char dirname[] = "in_dir";
567 
568     testStart("test_encode_file_directory");
569 
570     symbol = ZBarcode_Create();
571     assert_nonnull(symbol, "Symbol not created\n");
572 
573     (void) testUtilRmDir(dirname); // In case junk hanging around
574     ret = testUtilMkDir(dirname);
575     assert_zero(ret, "testUtilMkDir(%s) %d != 0 (%d: %s)\n", dirname, ret, errno, strerror(errno));
576 
577     ret = ZBarcode_Encode_File(symbol, dirname);
578     assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt);
579 
580     ret = testUtilRmDir(dirname);
581     assert_zero(ret, "testUtilRmDir(%s) %d != 0 (%d: %s)\n", dirname, ret, errno, strerror(errno));
582 
583     ZBarcode_Delete(symbol);
584 
585     testFinish();
586 }
587 
test_bad_args(void)588 static void test_bad_args(void) {
589     int ret;
590     struct zint_symbol *symbol;
591     char *data = "1";
592     char *filename = "1.png";
593     char *empty = "";
594 
595     testStart("test_bad_args");
596 
597     // These just return, no error
598     ZBarcode_Clear(NULL);
599     ZBarcode_Delete(NULL);
600 
601     ret = ZBarcode_Version();
602     assert_nonzero(ret >= 20901, "ZBarcode_Version() %d <= 20901\n", ret);
603 
604     assert_zero(ZBarcode_ValidID(0), "ZBarcode_ValidID(0) non-zero\n");
605     assert_zero(ZBarcode_ValidID(10), "ZBarcode_ValidID(10) non-zero\n"); // Note 10 remapped to BARCODE_EANX in ZBarcode_Encode() for tbarcode compat but not counted as valid
606 
607     ret = ZBarcode_Cap(0, ~0);
608     assert_zero(ret, "ZBarcode_Cap(0, ~0) ret 0x%X != 0\n", ret);
609     ret = ZBarcode_Cap(10, ~0);
610     assert_zero(ret, "ZBarcode_Cap(10, ~0) ret 0x%X != 0\n", ret);
611 
612     // NULL symbol
613     assert_equal(ZBarcode_Encode(NULL, (unsigned char *) data, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(NULL, data, 1) != ZINT_ERROR_INVALID_DATA\n");
614     assert_equal(ZBarcode_Print(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Print(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
615     assert_equal(ZBarcode_Buffer(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
616     assert_equal(ZBarcode_Buffer_Vector(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer_Vector(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
617     assert_equal(ZBarcode_Encode_and_Print(NULL, (unsigned char *) data, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
618     assert_equal(ZBarcode_Encode_and_Buffer(NULL, (unsigned char *) data, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
619     assert_equal(ZBarcode_Encode_File(NULL, filename), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(NULL, filename) != ZINT_ERROR_INVALID_DATA\n");
620     assert_equal(ZBarcode_Encode_File_and_Print(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n");
621     assert_equal(ZBarcode_Encode_File_and_Buffer(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n");
622 
623     symbol = ZBarcode_Create();
624     assert_nonnull(symbol, "Symbol not created\n");
625 
626     // NULL data/filename
627     symbol->errtxt[0] = '\0';
628     assert_equal(ZBarcode_Encode(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n");
629     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, NULL, 1) no errtxt\n");
630     symbol->errtxt[0] = '\0';
631     assert_equal(ZBarcode_Encode_and_Print(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
632     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) no errtxt\n");
633     symbol->errtxt[0] = '\0';
634     assert_equal(ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
635     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) no errtxt\n");
636     symbol->errtxt[0] = '\0';
637     assert_equal(ZBarcode_Encode_File(symbol, NULL), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, NULL) != ZINT_ERROR_INVALID_DATA\n");
638     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, NULL) no errtxt\n");
639     symbol->errtxt[0] = '\0';
640     assert_equal(ZBarcode_Encode_File_and_Print(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
641     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) no errtxt\n");
642     symbol->errtxt[0] = '\0';
643     assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
644     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) no errtxt\n");
645 
646     // Empty data/filename
647     symbol->errtxt[0] = '\0';
648     assert_equal(ZBarcode_Encode(symbol, (unsigned char *) empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
649     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, 0) no errtxt\n");
650     symbol->errtxt[0] = '\0';
651     assert_equal(ZBarcode_Encode_and_Print(symbol, (unsigned char *) empty, 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n");
652     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) no errtxt\n");
653     symbol->errtxt[0] = '\0';
654     assert_equal(ZBarcode_Encode_and_Buffer(symbol, (unsigned char *) empty, 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n");
655     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) no errtxt\n");
656     symbol->errtxt[0] = '\0';
657     assert_equal(ZBarcode_Encode_File(symbol, empty), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, empty) != ZINT_ERROR_INVALID_DATA\n");
658     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, empty) no errtxt\n");
659     symbol->errtxt[0] = '\0';
660     assert_equal(ZBarcode_Encode_File_and_Print(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
661     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Print(symbol, empty, 0) no errtxt\n");
662     symbol->errtxt[0] = '\0';
663     assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
664     assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) no errtxt\n");
665 
666     // Data too big
667     symbol->errtxt[0] = '\0';
668     assert_equal(ZBarcode_Encode(symbol, (unsigned char *) empty, 17401), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode(symbol, empty, 17401) != ZINT_ERROR_TOO_LONG\n");
669     assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, 17401) no errtxt\n");
670 
671     ZBarcode_Delete(symbol);
672 
673     testFinish();
674 }
675 
test_valid_id(void)676 static void test_valid_id(void) {
677 
678     int ret;
679     const char *name;
680     int symbol_id;
681 
682     testStart("test_valid_id");
683 
684     for (symbol_id = -1; symbol_id < 160; symbol_id++) {
685         ret = ZBarcode_ValidID(symbol_id);
686         name = testUtilBarcodeName(symbol_id);
687         assert_nonnull((char *) name, "testUtilBarcodeName(%d) NULL\n", symbol_id);
688         if (ret) {
689             assert_equal(ret, 1, "ZBarcode_Valid(%d) != 1\n", symbol_id);
690             assert_nonzero(*name != '\0', "testUtilBarcodeName(%d) empty when ZBarcode_Valid() true\n", symbol_id);
691         } else {
692             assert_zero(ret, "ZBarcode_Valid(%d) != 0\n", symbol_id);
693             assert_zero(*name, "testUtilBarcodeName(%d) non-empty when ZBarcode_Valid() false\n", symbol_id);
694         }
695     }
696 
697     testFinish();
698 }
699 
700 STATIC_UNLESS_ZINT_TEST int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string);
701 
test_error_tag(int index)702 static void test_error_tag(int index) {
703 
704     struct item {
705         int error_number;
706         int warn_level;
707         char *data;
708         int ret;
709         char *expected;
710     };
711     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
712     struct item data[] = {
713         /*  0*/ { ZINT_WARN_INVALID_OPTION, -1, "", ZINT_WARN_INVALID_OPTION, "Warning " },
714         /*  1*/ { ZINT_WARN_INVALID_OPTION, WARN_FAIL_ALL, "", ZINT_ERROR_INVALID_OPTION, "Error " },
715         /*  2*/ { ZINT_WARN_USES_ECI, -1, "", ZINT_WARN_USES_ECI, "Warning " },
716         /*  3*/ { ZINT_WARN_USES_ECI, WARN_FAIL_ALL, "", ZINT_ERROR_USES_ECI, "Error " },
717         /*  4*/ { ZINT_WARN_NONCOMPLIANT, -1, "", ZINT_WARN_NONCOMPLIANT, "Warning " },
718         /*  5*/ { ZINT_WARN_NONCOMPLIANT, WARN_FAIL_ALL, "", ZINT_ERROR_NONCOMPLIANT, "Error " },
719         /*  6*/ { ZINT_ERROR_TOO_LONG, WARN_DEFAULT, "", ZINT_ERROR_TOO_LONG, "Error " },
720         /*  7*/ { ZINT_WARN_USES_ECI, -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", ZINT_WARN_USES_ECI, "Warning 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" },
721         /*  8*/ { ZINT_WARN_USES_ECI, WARN_FAIL_ALL, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", ZINT_ERROR_USES_ECI, "Error 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123" },
722         /*  9*/ { ZINT_ERROR_INVALID_DATA, -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", ZINT_ERROR_INVALID_DATA, "Error 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123" },
723         /* 10*/ { ZINT_WARN_USES_ECI, -1, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_WARN_USES_ECI, "Warning 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" },
724         /* 11*/ { ZINT_WARN_USES_ECI, WARN_FAIL_ALL, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_ERROR_USES_ECI, "Error 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123" },
725         /* 12*/ { ZINT_ERROR_INVALID_DATA, -1, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_ERROR_INVALID_DATA, "Error 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123" },
726     };
727     int data_size = ARRAY_SIZE(data);
728     int i, ret;
729 
730     testStart("test_error_tag");
731 
732     for (i = 0; i < data_size; i++) {
733         struct zint_symbol symbol = {0};
734 
735         if (index != -1 && i != index) continue;
736 
737         symbol.warn_level = data[i].warn_level;
738 
739         ret = error_tag(&symbol, data[i].error_number, data[i].data);
740         assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
741         assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol.errtxt, data[i].expected);
742 
743         if ((int) strlen(data[i].data) < 100) {
744             strcpy(symbol.errtxt, data[i].data);
745             ret = error_tag(&symbol, data[i].error_number, NULL);
746             assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
747             assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol.errtxt, data[i].expected);
748         }
749     }
750 
751     testFinish();
752 }
753 
754 STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length);
755 
test_strip_bom(void)756 static void test_strip_bom(void) {
757 
758     int length, ret;
759     char data[] = "\357\273\277A"; // U+FEFF BOM, with "A"
760     char bom_only[] = "\357\273\277"; // U+FEFF BOM only
761     char buf[6];
762 
763     testStart("test_strip_bom");
764 
765     strcpy(buf, data);
766     length = (int) strlen(buf);
767     strip_bom((unsigned char *) buf, &length);
768     assert_equal(length, 1, "length %d != 1\n", length);
769     assert_zero(buf[1], "buf[1] %d != 0\n", buf[1]);
770 
771     // BOM not stripped if only data
772 
773     strcpy(buf, bom_only);
774     length = (int) strlen(buf);
775     strip_bom((unsigned char *) buf, &length);
776     assert_equal(length, 3, "BOM only length %d != 3\n", length);
777     ret = strcmp(buf, bom_only);
778     assert_zero(ret, "BOM only strcmp ret %d != 0\n", ret);
779 
780     testFinish();
781 }
782 
test_zero_outfile(void)783 static void test_zero_outfile(void) {
784 
785     int ret;
786     struct zint_symbol *symbol;
787     char *data = "1234";
788 
789     testStart("test_zero_outfile");
790 
791     symbol = ZBarcode_Create();
792     assert_nonnull(symbol, "Symbol not created\n");
793 
794     assert_nonzero(symbol->outfile[0], "ZBarcode_Create() outfile zero\n");
795     symbol->outfile[0] = '\0';
796 
797     ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0);
798     assert_zero(ret, "ZBarcode_Encode(%s) ret %d != 0 (%s)\n", data, ret, symbol->errtxt);
799     assert_zero(symbol->outfile[0], "ZBarcode_Encode() outfile non-zero\n");
800 
801     ret = ZBarcode_Print(symbol, 0);
802     assert_equal(ret, ZINT_ERROR_INVALID_OPTION, "ZBarcode_Print() ret %d != ZINT_ERROR_INVALID_OPTION (%s)\n", ret, symbol->errtxt);
803     assert_zero(symbol->outfile[0], "ZBarcode_Print() outfile non-zero\n");
804 
805     ret = ZBarcode_Buffer(symbol, 0);
806     assert_zero(ret, "ZBarcode_Buffer() ret %d != 0 (%s)\n", ret, symbol->errtxt);
807     assert_zero(symbol->outfile[0], "ZBarcode_Buffer() outfile non-zero\n");
808 
809     ZBarcode_Delete(symbol);
810 
811     testFinish();
812 }
813 
test_clear(void)814 static void test_clear(void) {
815 
816     int ret;
817     struct zint_symbol *symbol;
818     char *data = "1234";
819 
820     testStart("test_clear");
821 
822     symbol = ZBarcode_Create();
823     assert_nonnull(symbol, "Symbol not created\n");
824 
825     symbol->symbology = BARCODE_MAXICODE;
826     symbol->whitespace_width = 5;
827     symbol->whitespace_height = 5;
828     symbol->border_width = 2;
829     symbol->output_options = BARCODE_BOX;
830     strcpy(symbol->fgcolour, "000000AA");
831     strcpy(symbol->bgcolour, "FFFFFFAA");
832 
833     // Raster
834 
835     ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0);
836     assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt);
837 
838     assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n");
839     assert_nonzero(symbol->width, "ZBarcode_Encode() width 0\n");
840 
841     ret = ZBarcode_Buffer(symbol, 0);
842     assert_zero(ret, "ZBarcode_Buffer() ret %d != 0 (%s)\n", ret, symbol->errtxt);
843 
844     assert_nonnull(symbol->bitmap, "ZBarcode_Buffer() bitmap NULL\n");
845     assert_nonnull(symbol->alphamap, "ZBarcode_Buffer() alphamap NULL\n");
846     assert_nonzero(symbol->bitmap_width, "ZBarcode_Buffer() bitmap_width 0\n");
847     assert_nonzero(symbol->bitmap_height, "ZBarcode_Buffer() bitmap_height 0\n");
848 
849     assert_nonzero(symbol->rows, "ZBarcode_Buffer() rows 0\n");
850     assert_nonzero(symbol->width, "ZBarcode_Buffer() width 0\n");
851     assert_zero(symbol->bitmap_byte_length, "ZBarcode_Buffer() bitmap_byte_length %d != 0\n", (int) symbol->bitmap_byte_length);
852     assert_null(symbol->vector, "ZBarcode_Buffer() vector != NULL\n");
853 
854     ZBarcode_Clear(symbol);
855 
856     assert_null(symbol->bitmap, "ZBarcode_Buffer() bitmap != NULL\n");
857     assert_null(symbol->alphamap, "ZBarcode_Buffer() alphamap != NULL\n");
858     assert_zero(symbol->bitmap_width, "ZBarcode_Buffer() bitmap_width %d != 0\n", symbol->bitmap_width);
859     assert_zero(symbol->bitmap_height, "ZBarcode_Buffer() bitmap_height %d != 0\n", symbol->bitmap_height);
860 
861     assert_zero(symbol->rows, "ZBarcode_Buffer() rows %d != 0\n", symbol->rows);
862     assert_zero(symbol->width, "ZBarcode_Buffer() width %d != 0\n", symbol->width);
863     assert_zero(symbol->bitmap_byte_length, "ZBarcode_Buffer() bitmap_byte_length %d != 0\n", (int) symbol->bitmap_byte_length);
864     assert_null(symbol->vector, "ZBarcode_Buffer() vector != NULL\n");
865 
866     // Vector
867 
868     ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0);
869     assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt);
870 
871     assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n");
872     assert_nonzero(symbol->width, "ZBarcode_Encode() width 0\n");
873 
874     ret = ZBarcode_Buffer_Vector(symbol, 0);
875     assert_zero(ret, "ZBarcode_Buffer_Vector() ret %d != 0 (%s)\n", ret, symbol->errtxt);
876 
877     assert_nonnull(symbol->vector, "ZBarcode_Buffer_Vector() vector NULL\n");
878     assert_nonnull(symbol->vector->rectangles, "ZBarcode_Buffer_Vector() vector->rectangles NULL\n");
879     assert_nonnull(symbol->vector->hexagons, "ZBarcode_Buffer_Vector() vector->hexagons NULL\n");
880     assert_null(symbol->vector->strings, "ZBarcode_Buffer_Vector() vector->strings != NULL\n"); // MAXICODE no text
881     assert_nonnull(symbol->vector->circles, "ZBarcode_Buffer_Vector() vector->circles NULL\n");
882 
883     assert_nonzero(symbol->rows, "ZBarcode_Buffer_Vector() rows 0\n");
884     assert_nonzero(symbol->width, "ZBarcode_Buffer_Vector() width 0\n");
885     assert_null(symbol->bitmap, "ZBarcode_Buffer_Vector() bitmap != NULL\n");
886     assert_null(symbol->alphamap, "ZBarcode_Buffer_Vector() alphamap != NULL\n");
887     assert_zero(symbol->bitmap_byte_length, "ZBarcode_Buffer_Vector() bitmap_byte_length %d != 0\n", (int) symbol->bitmap_byte_length);
888 
889     ZBarcode_Clear(symbol);
890 
891     assert_null(symbol->vector, "ZBarcode_Buffer_Vector() vector != NULL\n");
892 
893     assert_zero(symbol->rows, "ZBarcode_Buffer_Vector() rows %d != 0\n", symbol->rows);
894     assert_zero(symbol->width, "ZBarcode_Buffer_Vector() width %d != 0\n", symbol->width);
895     assert_zero(symbol->bitmap_byte_length, "ZBarcode_Buffer_Vector() bitmap_byte_length %d != 0\n", (int) symbol->bitmap_byte_length);
896     assert_null(symbol->bitmap, "ZBarcode_Buffer_Vector() bitmap != NULL\n");
897     assert_null(symbol->alphamap, "ZBarcode_Buffer_Vector() alphamap != NULL\n");
898     assert_zero(symbol->bitmap_width, "ZBarcode_Buffer_Vector() bitmap_width %d != 0\n", symbol->bitmap_width);
899     assert_zero(symbol->bitmap_height, "ZBarcode_Buffer_Vector() bitmap_height %d != 0\n", symbol->bitmap_height);
900 
901     ZBarcode_Delete(symbol);
902 
903     testFinish();
904 }
905 
main(int argc,char * argv[])906 int main(int argc, char *argv[]) {
907 
908     testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
909         { "test_checks", test_checks, 1, 0, 1 },
910         { "test_symbologies", test_symbologies, 0, 0, 0 },
911         { "test_input_mode", test_input_mode, 1, 0, 1 },
912         { "test_escape_char_process", test_escape_char_process, 1, 1, 1 },
913         { "test_cap", test_cap, 1, 0, 0 },
914         { "test_encode_file_empty", test_encode_file_empty, 0, 0, 0 },
915         { "test_encode_file_too_large", test_encode_file_too_large, 0, 0, 0 },
916         { "test_encode_file_unreadable", test_encode_file_unreadable, 0, 0, 0 },
917         { "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 },
918         { "test_bad_args", test_bad_args, 0, 0, 0 },
919         { "test_valid_id", test_valid_id, 0, 0, 0 },
920         { "test_error_tag", test_error_tag, 1, 0, 0 },
921         { "test_strip_bom", test_strip_bom, 0, 0, 0 },
922         { "test_zero_outfile", test_zero_outfile, 0, 0, 0 },
923         { "test_clear", test_clear, 0, 0, 0 },
924     };
925 
926     testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
927 
928     testReport();
929 
930     return 0;
931 }
932