comparison mupdf-source/thirdparty/zint/backend/tests/test_filemem.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 libzint - the open source barcode library
3 Copyright (C) 2023-2024 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 /* SPDX-License-Identifier: BSD-3-Clause */
31
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <limits.h>
35 #include <locale.h>
36 #include <math.h>
37 #include <sys/stat.h>
38 #include "testcommon.h"
39 #include "../common.h"
40 #include "../filemem.h"
41
42 static void test_svg(const testCtx *const p_ctx) {
43 int debug = p_ctx->debug;
44
45 struct item {
46 int symbology;
47 int output_options;
48 char *outfile;
49 char *data;
50 int length;
51 int ret;
52
53 char *expected;
54 };
55 /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
56 struct item data[] = {
57 /* 0*/ { BARCODE_CODE128, BARCODE_MEMORY_FILE, "out.svg", "ABCDEF", -1, 0,
58 "<?xml version=\"1.0\" standalone=\"no\"?>\n"
59 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
60 "<svg width=\"202\" height=\"117\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"
61 " <desc>Zint Generated Symbol</desc>\n"
62 " <g id=\"barcode\" fill=\"#000000\">\n"
63 " <rect x=\"0\" y=\"0\" width=\"202\" height=\"117\" fill=\"#FFFFFF\"/>\n"
64 " <path d=\"M0 0h4v100h-4ZM6 0h2v100h-2ZM12 0h2v100h-2ZM22 0h2v100h-2ZM26 0h2v100h-2ZM34 0h4v100h-4ZM44 0h2v100h-2ZM52 0h2v100h-2ZM56 0h4v100h-4ZM66 0h2v100h-2ZM74 0h2v100h-2ZM82 0h4v100h-4ZM88 0h2v100h-2ZM92 0h4v100h-4ZM102 0h2v100h-2ZM110 0h2v100h-2ZM118 0h4v100h-4ZM124 0h2v100h-2ZM132 0h2v100h-2ZM140 0h4v100h-4ZM150 0h2v100h-2ZM154 0h2v100h-2ZM158 0h4v100h-4ZM168 0h6v100h-6ZM176 0h4v100h-4ZM186 0h6v100h-6ZM194 0h2v100h-2ZM198 0h4v100h-4Z\"/>\n"
65 " <text x=\"101\" y=\"113.34\" text-anchor=\"middle\" font-family=\"Arimo, Arial, sans-serif\" font-size=\"14\">\n"
66 " ABCDEF\n"
67 " </text>\n"
68 " </g>\n"
69 "</svg>\n"
70 },
71 };
72 int data_size = ARRAY_SIZE(data);
73 int i, length, ret;
74 struct zint_symbol *symbol = NULL;
75
76 testStartSymbol("test_svg", &symbol);
77
78 for (i = 0; i < data_size; i++) {
79
80 if (testContinue(p_ctx, i)) continue;
81
82 symbol = ZBarcode_Create();
83 assert_nonnull(symbol, "Symbol not created\n");
84
85 length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, data[i].output_options, data[i].data, data[i].length, debug);
86 strcpy(symbol->outfile, data[i].outfile);
87
88 ret = ZBarcode_Encode_and_Print(symbol, TU(data[i].data), length, 0);
89 assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_and_Print(%d) ret %d != %d (%s)\n",
90 i, data[i].symbology, ret, data[i].ret, symbol->errtxt);
91
92 if (ret < ZINT_ERROR) {
93 const int expected_size = (int) strlen(data[i].expected);
94
95 assert_nonnull(symbol->memfile, "i:%d memfile NULL (%s)\n", i, symbol->errtxt);
96
97 assert_equal(symbol->memfile_size, expected_size, "i:%d memfile_size %d != %d (%s)\n",
98 i, symbol->memfile_size, expected_size, symbol->errtxt);
99 ret = memcmp(symbol->memfile, data[i].expected, symbol->memfile_size);
100 assert_zero(ret, "i:%d memcmp() %d != 0\n", i, ret);
101 } else {
102 assert_null(symbol->memfile, "i:%d memfile != NULL (%s)\n", i, symbol->errtxt);
103 assert_zero(symbol->memfile_size, "i:%d memfile_size != 0 (%s)\n", i, symbol->errtxt);
104 }
105
106 ZBarcode_Delete(symbol);
107 }
108
109 testFinish();
110 }
111
112 #if defined(_WIN32) || (defined(__sun) && defined(__SVR4))
113 #define ZINT_TEST_NO_FMEMOPEN
114 #endif
115
116 #ifndef ZINT_TEST_NO_FMEMOPEN
117 extern FILE *fmemopen(void *buf, size_t size, const char *mode);
118 #endif
119
120 static void test_putsf(const testCtx *const p_ctx) {
121 int debug = p_ctx->debug;
122
123 struct item {
124 const char *prefix;
125 int dp;
126 float arg;
127 const char *locale;
128 const char *expected;
129 };
130 /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
131 struct item data[] = {
132 /* 0*/ { "", 2, 1234.123, "", "1234.12" },
133 /* 1*/ { "", 3, 1234.123, "", "1234.123" },
134 /* 2*/ { "prefix ", 4, 1234.123, "", "prefix 1234.123" },
135 /* 3*/ { "", 2, -1234.126, "", "-1234.13" },
136 /* 4*/ { "", 2, 1234.1, "", "1234.1" },
137 /* 5*/ { "", 3, 1234.1, "", "1234.1" },
138 /* 6*/ { "", 4, 1234.1, "", "1234.1" },
139 /* 7*/ { "", 2, 1234.0, "", "1234" },
140 /* 8*/ { "", 2, -1234.0, "", "-1234" },
141 /* 9*/ { "", 3, 1234.1234, "de_DE.UTF-8", "1234.123" },
142 /* 10*/ { "", 4, -1234.1234, "de_DE.UTF-8", "-1234.1234" },
143 /* 11*/ { "prefix ", 4, -1234.1234, "de_DE.UTF-8", "prefix -1234.1234" },
144 };
145 int data_size = ARRAY_SIZE(data);
146 int i, j;
147
148 struct zint_symbol symbol_data = {0};
149 struct zint_symbol *const symbol = &symbol_data;
150 struct filemem fm;
151 struct filemem *const fmp = &fm;
152 #ifndef ZINT_TEST_NO_FMEMOPEN
153 FILE *fp;
154 char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */
155 #endif
156
157 testStart("test_putsf");
158
159 for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */
160 #ifdef ZINT_TEST_NO_FMEMOPEN
161 if (j == 1) break; /* Skip file test on Windows/Solaris */
162 #endif
163 for (i = 0; i < data_size; i++) {
164 const char *locale = NULL;
165 int expected_size;
166
167 if (testContinue(p_ctx, i)) continue;
168
169 ZBarcode_Reset(symbol);
170 if (j == 1) {
171 #ifndef ZINT_TEST_NO_FMEMOPEN
172 buf[0] = '\0';
173 fp = fmemopen(buf, sizeof(buf), "w");
174 assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno));
175 #endif
176 } else {
177 symbol->output_options |= BARCODE_MEMORY_FILE;
178 }
179 assert_nonzero(fm_open(fmp, symbol, "w"), "i:%d: fm_open fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
180 if (j == 1) {
181 #ifndef ZINT_TEST_NO_FMEMOPEN
182 /* Hack in `fmemopen()` fp */
183 assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno));
184 fmp->fp = fp;
185 #endif
186 }
187
188 if (data[i].locale && data[i].locale[0]) {
189 locale = setlocale(LC_ALL, data[i].locale);
190 if (!locale) { /* May not be available - warn unless quiet mode */
191 if (!(debug & ZINT_DEBUG_TEST_LESS_NOISY)) {
192 printf("i:%d: Warning: locale \"%s\" not available\n", i, data[i].locale);
193 }
194 }
195 }
196
197 fm_putsf(data[i].prefix, data[i].dp, data[i].arg, fmp);
198
199 assert_nonzero(fm_close(fmp, symbol), "i:%d: fm_close fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
200
201 if (locale) {
202 assert_nonnull(setlocale(LC_ALL, locale), "i:%d: setlocale(%s) restore fail (%d, %s)\n",
203 i, locale, errno, strerror(errno));
204 }
205
206 if (j == 1) {
207 #ifndef ZINT_TEST_NO_FMEMOPEN
208 assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected);
209 #endif
210 } else {
211 expected_size = (int) strlen(data[i].expected);
212 assert_equal(symbol->memfile_size, expected_size, "i:%d: memfile_size %d != expected_size %d\n",
213 i, symbol->memfile_size, expected_size);
214 assert_nonnull(symbol->memfile, "i:%d memfile NULL\n", i);
215 assert_zero(memcmp(symbol->memfile, data[i].expected, expected_size), "i:%d: memcmp(%.*s, %.*s) != 0\n",
216 i, symbol->memfile_size, symbol->memfile, expected_size, data[i].expected);
217 }
218
219 ZBarcode_Clear(symbol);
220 }
221 }
222
223 testFinish();
224 }
225
226 static void test_printf(const testCtx *const p_ctx) {
227 int debug = p_ctx->debug;
228
229 int ret;
230 int j;
231 struct zint_symbol symbol_data = {0};
232 struct zint_symbol *const symbol = &symbol_data;
233 struct filemem fm;
234 struct filemem *const fmp = &fm;
235 const char outfile[] = "test_printf.tst";
236 unsigned char filebuf[32768];
237 int filebuf_size;
238
239 const char fmt1[] = "\n%s%04d\n\032\nwow\n\r\n%.2s\n"; /* '\032' SUB (^Z) */
240 const char expected1[] = "\ngosh0123\n\032\nwow\n\r\nge\n";
241 #ifdef _WIN32
242 /* On Windows, non-binary (i.e. text) files, LF -> LF+CR (note, actual files only, not memfiles) */
243 const char expected1_text_file[] = "\r\ngosh0123\r\n\032\r\nwow\r\n\r\r\nge\r\n";
244 #endif
245 const char *expected;
246 int expected_size;
247
248 (void)debug;
249
250 testStart("test_printf");
251
252 for (j = 0; j < 2; j++) { /* 1st memfile, then file */
253 ZBarcode_Reset(symbol);
254
255 /* Binary */
256 expected = expected1;
257 if (j == 1) {
258 strcpy(symbol->outfile, outfile);
259 } else {
260 symbol->output_options |= BARCODE_MEMORY_FILE;
261 }
262 ret = fm_open(fmp, symbol, "wb");
263 assert_equal(ret, 1, "fm_open ret %d != 1\n", ret);
264
265 ret = fm_printf(fmp, fmt1, "gosh", 123, "gee");
266 assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret);
267
268 ret = fm_close(fmp, symbol);
269 assert_equal(ret, 1, "fm_close ret %d != 1\n", ret);
270
271 expected_size = (int) strlen(expected);
272
273 if (j == 1) {
274 ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size);
275 assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret);
276 assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size);
277 assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n",
278 filebuf_size, filebuf, expected);
279 if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) {
280 assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
281 }
282 } else {
283 assert_nonnull(symbol->memfile, "memfile NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
284 assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n",
285 symbol->memfile_size, expected_size);
286 assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n",
287 symbol->memfile_size, symbol->memfile, expected);
288 }
289
290 /* Non-binary */
291 expected = expected1;
292 if (j == 1) {
293 strcpy(symbol->outfile, outfile);
294 #ifdef _WIN32
295 expected = expected1_text_file;
296 #endif
297 } else {
298 symbol->output_options |= BARCODE_MEMORY_FILE;
299 }
300 ret = fm_open(fmp, symbol, "w");
301 assert_equal(ret, 1, "fm_open ret %d != 1\n", ret);
302
303 ret = fm_printf(fmp, fmt1, "gosh", 123, "gee");
304 assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret);
305
306 ret = fm_close(fmp, symbol);
307 assert_equal(ret, 1, "fm_close ret %d != 1\n", ret);
308
309 expected_size = (int) strlen(expected);
310
311 if (j == 1) {
312 ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size);
313 assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret);
314 assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size);
315 assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n",
316 filebuf_size, filebuf, expected);
317 if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) {
318 assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
319 }
320 } else {
321 assert_nonnull(symbol->memfile, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
322 assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n",
323 symbol->memfile_size, expected_size);
324 assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n",
325 symbol->memfile_size, symbol->memfile, expected);
326 }
327
328 ZBarcode_Clear(symbol);
329 }
330
331 testFinish();
332 }
333
334 static void test_seek(const testCtx *const p_ctx) {
335 int debug = p_ctx->debug;
336
337 int ret;
338 int j;
339 struct zint_symbol symbol_data = {0};
340 struct zint_symbol *const symbol = &symbol_data;
341 struct filemem fm;
342 struct filemem *const fmp = &fm;
343 const char outfile[] = "test_seek.tst";
344
345 (void)debug;
346
347 testStart("test_seek");
348
349 for (j = 0; j < 2; j++) { /* 1st memfile, then file */
350 ZBarcode_Reset(symbol);
351
352 if (j == 1) {
353 strcpy(symbol->outfile, outfile);
354 } else {
355 symbol->output_options |= BARCODE_MEMORY_FILE;
356 }
357 ret = fm_open(fmp, symbol, "wb");
358 assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret);
359
360 ret = fm_puts("1234567890", fmp);
361 assert_equal(ret, 1, "j:%d fm_puts ret %d != 1\n", j, ret);
362 if (j != 1) {
363 assert_nonnull(fmp->mem, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
364 assert_equal(fmp->mempos, 10, "mempos %d != 10\n", (int) fmp->mempos);
365 assert_zero(memcmp(fmp->mem, "1234567890", fmp->mempos), "memcmp fail\n");
366 }
367
368 ret = fm_seek(fmp, -10, SEEK_CUR);
369 assert_equal(ret, 1, "j:%d fm_seek ret %d != 1 (%d: %s)\n", j, ret, fmp->err, strerror(fmp->err));
370 ret = fm_error(fmp);
371 assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret);
372 ret = (int) fm_tell(fmp);
373 assert_zero(ret, "j:%d fm_tell ret %d != 0\n", j, ret);
374
375 ret = fm_seek(fmp, 0, SEEK_END);
376 assert_equal(ret, 1, "j:%d fm_seek ret %d != 1\n", j, ret);
377 ret = fm_error(fmp);
378 assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret);
379 ret = (int) fm_tell(fmp);
380 assert_equal(ret, 10, "j:%d fm_tell ret %d != 10\n", j, ret);
381
382 ret = fm_seek(fmp, -1, SEEK_SET);
383 assert_zero(ret, "j:%d fm_seek ret %d != 1\n", j, ret);
384 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
385
386 ret = fm_close(fmp, symbol);
387 assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret);
388 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
389
390 if (j == 1) {
391 assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
392 }
393
394 ret = fm_open(fmp, symbol, "wb");
395 assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret);
396
397 ret = fm_seek(fmp, LONG_MAX, SEEK_CUR);
398 if (j == 1) { /* May work on some file systems */
399 if (ret == 0) {
400 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
401 }
402 } else {
403 assert_zero(ret, "j:%d fm_seek ret %d != 0\n", j, ret);
404 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
405 }
406
407 ret = fm_close(fmp, symbol);
408 if (j == 1) { /* See above */
409 if (ret == 0) {
410 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
411 }
412 } else {
413 assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret);
414 assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
415 }
416
417 if (j == 1) {
418 assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
419 }
420
421 ZBarcode_Clear(symbol);
422 }
423
424 testFinish();
425 }
426
427 static void test_large(const testCtx *const p_ctx) {
428 int debug = p_ctx->debug;
429
430 int ret;
431 struct zint_symbol *symbol = NULL;
432 char data[] = "1";
433 int expected_size = 354879;
434
435 (void)debug;
436
437 testStart("test_large");
438
439 symbol = ZBarcode_Create();
440 assert_nonnull(symbol, "Symbol not created\n");
441
442 symbol->symbology = BARCODE_HANXIN;
443 symbol->output_options |= BARCODE_MEMORY_FILE;
444 strcpy(symbol->outfile, "out.gif"); /* Use GIF in case ZINT_NO_PNG */
445 symbol->option_2 = 84;
446 symbol->scale = 10.0f; /* Could go up to 86.5 (pixel buffer 0x3FB913B1, file size 8868579) but very very slow */
447
448 ret = ZBarcode_Encode_and_Print(symbol, TU(data), -1, 0);
449 assert_zero(ret, "ZBarcode_Encode_and_Print ret %d != 0 (%s)\n", ret, symbol->errtxt);
450 assert_nonnull(symbol->memfile, "memfile NULL (%s)\n", symbol->errtxt);
451 assert_equal(symbol->memfile_size, expected_size, "memfile_size %d != expected %d\n",
452 symbol->memfile_size, expected_size);
453
454 symbol->scale = 87.0f; /* Too large (pixel buffer > 1GB) */
455 ret = ZBarcode_Print(symbol, 0);
456 assert_equal(ret, ZINT_ERROR_MEMORY, "ZBarcode_Print ret %d != ZINT_ERROR_MEMORY (%s)\n", ret, symbol->errtxt);
457
458 ZBarcode_Delete(symbol);
459
460 testFinish();
461 }
462
463 int main(int argc, char *argv[]) {
464
465 testFunction funcs[] = { /* name, func */
466 { "test_svg", test_svg },
467 { "test_putsf", test_putsf },
468 { "test_printf", test_printf },
469 { "test_seek", test_seek },
470 { "test_large", test_large },
471 };
472
473 testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
474
475 testReport();
476
477 return 0;
478 }
479
480 /* vim: set ts=4 sw=4 et : */
481