1
0
mirror of https://git.code.sf.net/p/zint/code synced 2026-01-27 13:55:57 +00:00

CODE128: fix not handling FNC1 at end of data when in manual

switching mode or any FNC1 after manual C mode selected and no
  other non-C data - found by fuzz test "fuzz_data" - 2nd ever
  trophy!
qr.h: fix typo (props https://github.com/crate-ci/typos)
This commit is contained in:
gitlost
2026-01-12 20:38:15 +00:00
parent a718c79237
commit 6e533c7a0a
8 changed files with 158 additions and 41 deletions

View File

@@ -1,4 +1,4 @@
Version 2.16.0.9 (dev) not released yet (2025-12-31) Version 2.16.0.9 (dev) not released yet (2025-01-12)
==================================================== ====================================================
**Incompatible changes** **Incompatible changes**
@@ -15,6 +15,8 @@ Changes
Bugs Bugs
---- ----
- CODE128: fix not handling FNC1 at end of data when in manual switching mode
or any FNC1 after manual C mode selected and no other non-C data
- CLI: fix "--scalexdimdp" X-dim inch units being divided instead of multiplied - CLI: fix "--scalexdimdp" X-dim inch units being divided instead of multiplied
on conversion to mm on conversion to mm

View File

@@ -1,7 +1,7 @@
/* code128.c - Handles Code 128 and GS1-128 */ /* code128.c - Handles Code 128 and GS1-128 */
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008-2025 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2026 Robin Stuart <rstuart114@gmail.com>
Bugfixes thanks to Christian Sakowski and BogDan Vatra Bugfixes thanks to Christian Sakowski and BogDan Vatra
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -446,21 +446,24 @@ INTERNAL int zint_code128(struct zint_symbol *symbol, unsigned char source[], in
have_a |= !mask_0x60; have_a |= !mask_0x60;
have_b |= mask_0x60 == 0x60; have_b |= mask_0x60 == 0x60;
} }
} else if (have_fnc1) {
have_a = have_b = have_c = 1;
for (i = 0; i < length; i++) {
have_extended |= src[i] & 0x80;
}
} else { } else {
int prev_digit, digit = 0; int prev_digit, digit = 0;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
const unsigned char ch = src[i]; const unsigned char ch = src[i];
const int is_fnc1 = ch == '\x1D' && fncs[i]; const unsigned char mask_0x60 = ch & 0x60; /* 0 for (ch & 0x7F) < 32, 0x60 for (ch & 0x7F) >= 96 */
if (!is_fnc1) { const int manual = manuals[i];
const unsigned char mask_0x60 = ch & 0x60; /* 0 for (ch & 0x7F) < 32, 0x60 for (ch & 0x7F) >= 96 */ assert(!(ch == '\x1D' && fncs[i])); /* Can't be FNC1 */
const int manual = manuals[i]; have_extended |= ch & 0x80;
have_extended |= ch & 0x80; have_a |= !mask_0x60 || manual == C128_A0;
have_a |= !mask_0x60 || manual == C128_A0; have_b |= mask_0x60 == 0x60 || manual == C128_B0;
have_b |= mask_0x60 == 0x60 || manual == C128_B0; prev_digit = digit;
prev_digit = digit; digit = z_isdigit(ch);
digit = z_isdigit(ch); have_c |= prev_digit && digit;
have_c |= prev_digit && digit;
}
} }
} }
c128_set_priority(priority, have_a, have_b, have_c, have_extended); c128_set_priority(priority, have_a, have_b, have_c, have_extended);

View File

@@ -336,7 +336,7 @@ static const unsigned int rmqr_format_info_right[64] = {
}; };
/* Pre-calculated QR and MicroQR mask tables, generated by "backend/tools/gen_qr_masks.php", /* Pre-calculated QR and MicroQR mask tables, generated by "backend/tools/gen_qr_masks.php",
based on lowest common periodicy of the masks (6x12): based on lowest common periodicity of the masks (6x12):
QR: 000: 2x2, 001: 1x2, 010: 3x1, 011: 3x3, 100: 6x4, 101: 6x6, 110: 6x6, 111: 6x6 QR: 000: 2x2, 001: 1x2, 010: 3x1, 011: 3x3, 100: 6x4, 101: 6x6, 110: 6x6, 111: 6x6
MicroQR: 00 (001), 01 (100), 10 (110), 11 (111) MicroQR: 00 (001), 01 (100), 10 (110), 11 (111)
Taken from Barcode Writer in Pure PostScript (BWIPP) Taken from Barcode Writer in Pure PostScript (BWIPP)

View File

@@ -14,7 +14,7 @@
/* NOLINTEND(clang-diagnostic-comment) */ /* NOLINTEND(clang-diagnostic-comment) */
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2024-2025 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2024-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -866,6 +866,15 @@ static const struct item data_data[] = {
/* 40*/ { 6, BARCODE_DOTCODE, -1, -1, -1, -1, -1, "\237", -1 }, /* As above L1090 */ /* 40*/ { 6, BARCODE_DOTCODE, -1, -1, -1, -1, -1, "\237", -1 }, /* As above L1090 */
/* 41*/ { 0, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "\223\223\223\223\223\200\000\060\060\020\122\104\060\343\000\000\040\104\104\104\104\177\377\040\000\324\336\000\000\000\000\104\060\060\060\060\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\060\104\104\000\000\000\040\104\104\104\104\177\377\377\377\324\336\000\000\000\000\104\377\104\001\104\104\104\104\104\104\233\233\060\060\060\060\060\060\060\060\060\325\074", 107 }, /* #181 Nico Gunkel OSS-Fuzz - original OSS-Fuzz triggering data */ /* 41*/ { 0, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "\223\223\223\223\223\200\000\060\060\020\122\104\060\343\000\000\040\104\104\104\104\177\377\040\000\324\336\000\000\000\000\104\060\060\060\060\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\060\104\104\000\000\000\040\104\104\104\104\177\377\377\377\324\336\000\000\000\000\104\377\104\001\104\104\104\104\104\104\233\233\060\060\060\060\060\060\060\060\060\325\074", 107 }, /* #181 Nico Gunkel OSS-Fuzz - original OSS-Fuzz triggering data */
/* 42*/ { 1, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789", -1 }, /* Add 6 lowercase a's so 6 SHIFTS inserted so 6 + 138 (max input len) = 144 and numbers come at end of buffer */ /* 42*/ { 1, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789", -1 }, /* Add 6 lowercase a's so 6 SHIFTS inserted so 6 + 138 (max input len) = 144 and numbers come at end of buffer */
/* 43*/ { 0, BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, -1, -1, -1,
"\003\134\136\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\000\000\051\000\054\103\103\103\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\242\053\134\136\061\067\242\242\242\242\242"
"\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242"
"\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242"
"\136\136",
162
}, /* fuzz_data (1st) */
}; };
/* GS1_MODE data */ /* GS1_MODE data */

View File

@@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020-2025 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -106,7 +106,7 @@ static void test_large(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192] = {0}; /* Suppress clang -fsanitize=memory false positive */ char ret_buf[8192] = {0}; /* Suppress clang -fsanitize=memory false positive */
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -294,7 +294,7 @@ static void test_hrt(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -419,7 +419,7 @@ static void test_reader_init(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do ZXing-C++ test if asked, too slow otherwise */ /* Only do zxing-cpp test if asked, too slow otherwise */
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
testStartSymbol(p_ctx->func_name, &symbol); testStartSymbol(p_ctx->func_name, &symbol);
@@ -649,6 +649,17 @@ static void test_input(const testCtx *const p_ctx) {
/*139*/ { UNICODE_MODE, "12é12é", -1, 0, 123, 0, 1, "(11) 105 12 100 100 73 17 18 100 73 17 106", "StartC 12 CodeB FNC4 é 1 2 FNC4 é; BWIPP different encodation (StartB)" }, /*139*/ { UNICODE_MODE, "12é12é", -1, 0, 123, 0, 1, "(11) 105 12 100 100 73 17 18 100 73 17 106", "StartC 12 CodeB FNC4 é 1 2 FNC4 é; BWIPP different encodation (StartB)" },
/*140*/ { UNICODE_MODE, "1234é123456é", -1, 0, 167, 1, 1, "(15) 105 12 34 100 100 73 99 12 34 56 100 100 73 15 106", "StartC 12 34 CodeB FNC4 é CodeC 12 34 56 CodeB FNC4 é" }, /*140*/ { UNICODE_MODE, "1234é123456é", -1, 0, 167, 1, 1, "(15) 105 12 34 100 100 73 99 12 34 56 100 100 73 15 106", "StartC 12 34 CodeB FNC4 é CodeC 12 34 56 CodeB FNC4 é" },
/*141*/ { DATA_MODE, "\256^a\357\033\270\017,\274u$B\305\311\006\011]\273\025u\315\2638\263\333", -1, 0, 453, 1, 899, "(41) 104 100 14 62 65 100 79 101 91 101 24 79 12 101 28 98 85 4 34 101 37 101 41 70 73 61", "" }, /*141*/ { DATA_MODE, "\256^a\357\033\270\017,\274u$B\305\311\006\011]\273\025u\315\2638\263\333", -1, 0, 453, 1, 899, "(41) 104 100 14 62 65 100 79 101 91 101 24 79 12 101 28 98 85 4 34 101 37 101 41 70 73 61", "" },
/*142*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1", -1, 0, 46, 0, 0, "(4) 105 102 1 106", "StartC FNC1; From fuzz 2026-01-12; BWIPP see below; zxing-cpp empty text" },
/*143*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^A\\^1", -1, 0, 46, 0, 0, "(4) 103 102 102 106", "StartA FNC1; From fuzz 2026-01-12; BWIPP see below; zxing-cpp empty text" },
/*144*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^B\\^1", -1, 0, 46, 1, 0, "(4) 104 102 0 106", "StartB FNC1; From fuzz 2026-01-12; zxing-cpp empty text" },
/*145*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^1", -1, 0, 46, 0, 0, "(4) 105 102 1 106", "StartC FNC1; BWIPP see above; zxing-cpp empty text" },
/*146*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1A", -1, 0, 68, 0, 3, "(6) 105 102 100 33 94 106", "StartC CodeB FNC1 A; BWIPP see below" },
/*147*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^A\\^1A", -1, 0, 57, 0, 3, "(5) 103 102 33 65 106", "StartA FNC1 A; BWIPP see below" },
/*148*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^B\\^1A", -1, 0, 57, 1, 3, "(5) 104 102 33 66 106", "StartB FNC1 A" },
/*149*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^1A", -1, 0, 57, 1, 3, "(5) 104 102 33 66 106", "StartB FNC1 A" },
/*150*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "A\\^1", -1, 0, 57, 1, 3, "(5) 104 33 102 32 106", "StartB A FNC1" },
/*151*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^112", -1, 0, 57, 1, 3, "(5) 105 102 12 25 106", "StartC FNC1 12" },
/*152*/ { UNICODE_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1é", -1, 0, 79, 0, 1, "(7) 105 102 100 100 73 72 106", "StartC FNC1 CodeB FNC4 é; BWIPP different encodation (StartB)" },
}; };
const int data_size = ARRAY_SIZE(data); const int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@@ -660,7 +671,7 @@ static void test_input(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -719,22 +730,28 @@ static void test_input(const testCtx *const p_ctx) {
} }
} }
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
int cmp_len, ret_len; if (!data[i].zxingcpp_cmp) {
char modules_dump[4096]; if (debug & ZINT_DEBUG_TEST_PRINT) {
assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i); printf("i:%d %s not zxing-cpp compatible (%s)\n",
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, i, testUtilBarcodeName(symbol->symbology), data[i].comment);
"i:%d testUtilModulesDump == -1\n", i); }
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, } else {
cmp_buf, sizeof(cmp_buf), &cmp_len); int cmp_len, ret_len;
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", char modules_dump[4096];
i, testUtilBarcodeName(symbol->symbology), ret); assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1,
"i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp,
cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n",
i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length,
NULL /*primary*/, ret_buf, &ret_len); NULL /*primary*/, ret_buf, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n", assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg,
testUtilEscape(cmp_buf, cmp_len, escaped, sizeof(escaped)), testUtilEscape(cmp_buf, cmp_len, escaped, sizeof(escaped)),
testUtilEscape(ret_buf, ret_len, escaped2, sizeof(escaped2))); testUtilEscape(ret_buf, ret_len, escaped2, sizeof(escaped2)));
}
} }
} }
} }
@@ -798,7 +815,7 @@ static void test_gs1_128_input(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -924,7 +941,7 @@ static void test_hibc_input(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -1215,7 +1232,7 @@ static void test_dpd_input(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -1340,8 +1357,8 @@ static void test_upu_s10_input(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do ZXing-C++ test if asked, too slow otherwise */ /* Only do zxing-cpp test if asked, too slow otherwise */
/* Only do ZXing-C++ test if asked, too slow otherwise */ /* Only do zxing-cpp test if asked, too slow otherwise */
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
testStartSymbol(p_ctx->func_name, &symbol); testStartSymbol(p_ctx->func_name, &symbol);
@@ -1587,7 +1604,7 @@ static void test_encode(const testCtx *const p_ctx) {
char cmp_msg[1024]; char cmp_msg[1024];
char ret_buf[8192]; char ret_buf[8192];
/* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript();
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
@@ -1673,6 +1690,91 @@ static void test_encode(const testCtx *const p_ctx) {
testFinish(); testFinish();
} }
static void test_fuzz(const testCtx *const p_ctx) {
int debug = p_ctx->debug;
struct item {
int symbology;
int input_mode;
int option_1;
int option_2;
const char *data;
int length;
int ret;
const char *expected_errtxt;
int zxingcpp_cmp;
};
/* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
static const struct item data[] = {
/* 0*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, -1,
"\003\134\136\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\000\000\051\000\054\103\103\103\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\242\053\134\136\061\067\242\242\242\242\242"
"\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242"
"\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242"
"\136\136",
162, ZINT_ERROR_TOO_LONG, "Error 341: Input too long, requires 167 symbol characters (maximum 102)", 3
}, /* fuzz_data (2nd, 2026-01-12) */
};
const int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol *symbol = NULL;
char escaped[8192];
char cmp_buf[32768];
char cmp_msg[8192];
/* Only do zxing-cpp test if asked, too slow otherwise */
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder();
testStartSymbol(p_ctx->func_name, &symbol);
for (i = 0; i < data_size; i++) {
if (testContinue(p_ctx, i)) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/,
data[i].data, data[i].length, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n",
i, ret ? "set" : "empty", symbol->errtxt);
assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n",
i, symbol->errtxt, data[i].expected_errtxt);
if (ret < ZINT_ERROR) {
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
int cmp_len, ret_len;
char modules_dump[22801 + 1];
assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i);
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1,
"i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp,
cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n",
i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/,
escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len,
escaped);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func */ testFunction funcs[] = { /* name, func */
@@ -1687,6 +1789,7 @@ int main(int argc, char *argv[]) {
{ "test_dpd_input", test_dpd_input }, { "test_dpd_input", test_dpd_input },
{ "test_upu_s10_input", test_upu_s10_input }, { "test_upu_s10_input", test_upu_s10_input },
{ "test_encode", test_encode }, { "test_encode", test_encode },
{ "test_fuzz", test_fuzz },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));