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_utf8_to_unicode(int index,int debug)34 static void test_utf8_to_unicode(int index, int debug) {
35
36 struct item {
37 char *data;
38 int length;
39 int disallow_4byte;
40 int ret;
41 int ret_length;
42 unsigned int expected_vals[20];
43 char *comment;
44 };
45 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
46 struct item data[] = {
47 /* 0*/ { "", -1, 1, 0, 0, {0}, "" },
48 /* 1*/ { "\000a\302\200\340\240\200", 7, 1, 0, 4, { 0, 'a', 0x80, 0x800 }, "NUL a C280 E0A080" },
49 /* 2*/ { "\357\277\277", -1, 1, 0, 1, { 0xFFFF }, "EFBFBF" },
50 /* 3*/ { "\360\220\200\200", -1, 1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Four-byte F0908080" },
51 /* 4*/ { "a\200b", -1, 1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Orphan continuation 0x80" },
52 };
53 int data_size = ARRAY_SIZE(data);
54 int i, length, ret;
55
56 unsigned int vals[20];
57 struct zint_symbol symbol = {0};
58
59 testStart("test_utf8_to_unicode");
60
61 symbol.debug = debug;
62
63 for (i = 0; i < data_size; i++) {
64 int ret_length;
65
66 if (index != -1 && i != index) continue;
67
68 length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
69 ret_length = length;
70
71 ret = utf8_to_unicode(&symbol, (unsigned char *) data[i].data, vals, &ret_length, data[i].disallow_4byte);
72 assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
73 if (ret == 0) {
74 int j;
75 assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length);
76 for (j = 0; j < ret_length; j++) {
77 assert_equal(vals[j], data[i].expected_vals[j], "i:%d vals[%d] %04X != %04X\n", i, j, vals[j], data[i].expected_vals[j]);
78 }
79 }
80 }
81
82 testFinish();
83 }
84
test_set_height(int index,int debug)85 static void test_set_height(int index, int debug) {
86
87 struct item {
88 int rows;
89 int row_height[20];
90 float height;
91
92 float min_row_height;
93 float default_height;
94 float max_height;
95 int no_errtxt;
96
97 int ret;
98 float expected_height;
99 char *expected_errtxt;
100 char *comment;
101 };
102 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
103 struct item data[] = {
104 /* 0*/ { 0, { 0 }, 0, 0, 0, 0, 0, 0, 0.5, "", "" },
105 /* 1*/ { 2, { 1, 1 }, 2, 0, 0, 0, 0, 0, 2, "", "zero_count == 0, fixed height only" },
106 /* 2*/ { 2, { 1, 1 }, 2, 0, 0, 1, 1, ZINT_WARN_NONCOMPLIANT, 2, "", "zero_count == 0, height < max height" },
107 /* 3*/ { 2, { 1, 1 }, 2, 0, 0, 1, 0, ZINT_WARN_NONCOMPLIANT, 2, "248: Height not compliant with standards", "zero_count == 0, height < max height" },
108 /* 4*/ { 2, { 2, 0 }, 2, 0, 0, 0, 0, 0, 2.5, "", "zero_count != 0, height 2" },
109 /* 5*/ { 2, { 2, 0 }, 2, 1, 0, 0, 1, ZINT_WARN_NONCOMPLIANT, 2.5, "", "zero_count != 0, row_height < min_row_height" },
110 /* 6*/ { 2, { 2, 0 }, 2, 1, 0, 0, 0, ZINT_WARN_NONCOMPLIANT, 2.5, "247: Height not compliant with standards", "zero_count != 0, row_height < min_row_height" },
111 /* 7*/ { 2, { 2, 0 }, 0, 0, 20, 0, 0, 0, 22, "", "zero_count != 0, default_height 20" },
112 /* 8*/ { 2, { 2, 0 }, 20, 0, 20, 0, 0, 0, 20, "", "zero_count != 0, height 20" },
113 /* 9*/ { 2, { 2, 0 }, 0, 2, 0, 0, 0, 0, 4, "", "zero_count != 0, min_row_height 2" },
114 };
115 int data_size = ARRAY_SIZE(data);
116 int i, ret;
117
118 struct zint_symbol symbol;
119
120 testStart("set_height");
121
122 symbol.debug = debug;
123
124 for (i = 0; i < data_size; i++) {
125 int j;
126
127 if (index != -1 && i != index) continue;
128
129 memset(&symbol, 0, sizeof(symbol));
130 symbol.rows = data[i].rows;
131 for (j = 0; j < ARRAY_SIZE(data[i].row_height); j++) {
132 symbol.row_height[j] = data[i].row_height[j];
133 }
134 symbol.height = data[i].height;
135
136 ret = set_height(&symbol, data[i].min_row_height, data[i].default_height, data[i].max_height, data[i].no_errtxt);
137 assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
138 assert_equal(symbol.height, data[i].expected_height, "i:%d symbol.height %g != %g\n", i, symbol.height, data[i].expected_height);
139 assert_zero(strcmp(symbol.errtxt, data[i].expected_errtxt), "i:%d errtxt %s != %s\n", i, symbol.errtxt, data[i].expected_errtxt);
140 }
141
142 testFinish();
143 }
144
test_is_valid_utf8(int index)145 static void test_is_valid_utf8(int index) {
146
147 struct item {
148 char *data;
149 int length;
150 int ret;
151 char *comment;
152 };
153 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
154 struct item data[] = {
155 /* 0*/ { "", -1, 1, "" },
156 /* 1*/ { "abcdefghijklmnopqrstuvwxyz", -1, 1, "" },
157 /* 2*/ { "éa", -1, 1, "" },
158 /* 3*/ { "a\000b", 3, 1, "Embedded nul" },
159 /* 4*/ { "\357\273\277a", -1, 1, "Bom" },
160
161 /* 5*/ { "a\xC2", -1, 0, "Missing 2nd byte" },
162 /* 6*/ { "a\200b", -1, 0, "Orphan continuation 0x80" },
163 /* 7*/ { "\300\201", -1, 0, "Overlong 0xC081" },
164 /* 8*/ { "\355\240\200", -1, 0, "Surrogate 0xEDA080" },
165 };
166 int data_size = ARRAY_SIZE(data);
167 int i, length, ret;
168
169 testStart("test_is_valid_utf8");
170
171 for (i = 0; i < data_size; i++) {
172
173 if (index != -1 && i != index) continue;
174
175 length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
176
177 ret = is_valid_utf8((const unsigned char *) data[i].data, length);
178 assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
179 }
180
181 testFinish();
182 }
183
test_debug_test_codeword_dump_int(int index,int debug)184 static void test_debug_test_codeword_dump_int(int index, int debug) {
185
186 struct item {
187 int codewords[50];
188 int length;
189 char *expected;
190 };
191 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
192 struct item data[] = {
193 /* 0*/ { { 2147483647, -2147483646, 2147483647, 0, 2147483647, 2147483647, 2147483647, 2147483647, 123456 }, 10, "(10) 2147483647 -2147483646 2147483647 0 2147483647 2147483647 2147483647 2147483647 123456" },
194 /* 1*/ { { 2147483647, -2147483646, 2147483647, 0, 2147483647, 2147483647, 2147483647, 2147483647, 1234567 }, 10, "(10) 2147483647 -2147483646 2147483647 0 2147483647 2147483647 2147483647 2147483647" },
195 };
196 int data_size = ARRAY_SIZE(data);
197 int i;
198
199 struct zint_symbol symbol = {0};
200
201 testStart("test_debug_test_codeword_dump_int");
202
203 symbol.debug = debug;
204
205 for (i = 0; i < data_size; i++) {
206
207 if (index != -1 && i != index) continue;
208
209 debug_test_codeword_dump_int(&symbol, data[i].codewords, data[i].length);
210 assert_nonzero(strlen(symbol.errtxt) < 92, "i:%d strlen(%s) >= 92 (%d)\n", i, symbol.errtxt, (int) strlen(symbol.errtxt));
211 assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (%d, %d)\n", i, symbol.errtxt, data[i].expected, (int) strlen(symbol.errtxt), (int) strlen(data[i].expected));
212 }
213
214 testFinish();
215 }
216
main(int argc,char * argv[])217 int main(int argc, char *argv[]) {
218
219 testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
220 { "test_utf8_to_unicode", test_utf8_to_unicode, 1, 0, 1 },
221 { "test_set_height", test_set_height, 1, 0, 1 },
222 { "test_is_valid_utf8", test_is_valid_utf8, 1, 0, 0 },
223 { "test_debug_test_codeword_dump_int", test_debug_test_codeword_dump_int, 1, 0, 1 },
224 };
225
226 testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
227
228 testReport();
229
230 return 0;
231 }
232