From 888db0bf0090b82ba949839dbf9d1e5fd0f1ca10 Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 30 Nov 2023 09:12:11 +0000 Subject: [PATCH] QRCODE: fix out-of-bounds crash due to incorrect mode costings for GS1 percents in `qr_in_alpha()`, ticket #300, props Andre Maute; also defensively re-calc version 40 mode to prevent possible further crashes common: move `debug_print_escape()` from library to common --- ChangeLog | 2 + backend/common.c | 15 ++ backend/common.h | 2 + backend/library.c | 14 -- backend/qr.c | 64 +++++-- backend/tests/test_dmatrix.c | 39 ++-- backend/tests/test_dotcode.c | 32 ++-- backend/tests/test_gridmtx.c | 25 +-- backend/tests/test_hanxin.c | 28 +-- backend/tests/test_qr.c | 350 ++++++++++++++++++++++++++--------- backend/tests/test_ultra.c | 34 ++-- backend/tests/testcommon.c | 43 +++-- backend/tests/testcommon.h | 2 +- 13 files changed, 445 insertions(+), 205 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7062e66a..8da1ffe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -129,6 +129,8 @@ Bugs - PDF417: fix out-of-bounds crash in `pdf_text_submode_length()` and out-of-bounds crash on overrunning string and codeword buffers, ticket #300, props Andre Maute +- QRCODE: fix out-of-bounds crash due to incorrect mode costings for GS1 + percents in `qr_in_alpha()`, ticket #300, props Andre Maute Version 2.12.0 (2022-12-12) diff --git a/backend/common.c b/backend/common.c index ee8dbcde..339e8a81 100644 --- a/backend/common.c +++ b/backend/common.c @@ -592,6 +592,21 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s } } +/* Helper for ZINT_DEBUG_PRINT to put all but graphical ASCII in angle brackets */ +INTERNAL char *debug_print_escape(const unsigned char *source, const int first_len, char *buf) { + int i, j = 0; + for (i = 0; i < first_len; i++) { + const unsigned char ch = source[i]; + if (ch < 32 || ch >= 127) { + j += sprintf(buf + j, "<%03o>", ch & 0xFF); + } else { + buf[j++] = ch; + } + } + buf[j] = '\0'; + return buf; +} + #ifdef ZINT_TEST /* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */ INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length) { diff --git a/backend/common.h b/backend/common.h index e37bf1c5..c10d4efd 100644 --- a/backend/common.h +++ b/backend/common.h @@ -272,6 +272,8 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s struct zint_seg local_segs[]); +INTERNAL char *debug_print_escape(const unsigned char *source, const int first_len, char *buf); + #ifdef ZINT_TEST /* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */ INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length); diff --git a/backend/library.c b/backend/library.c index 80d5f825..08221d42 100644 --- a/backend/library.c +++ b/backend/library.c @@ -677,20 +677,6 @@ static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], c return error_number; } -/* Helper for ZINT_DEBUG_PRINT to put all but graphical ASCII in angle brackets */ -static void debug_print_escape(const unsigned char *source, const int first_len, char *buf) { - int i, j = 0; - for (i = 0; i < first_len; i++) { - const unsigned char ch = source[i]; - if (ch < 32 || ch >= 127) { - j += sprintf(buf + j, "<%03o>", ch & 0xFF); - } else { - buf[j++] = ch; - } - } - buf[j] = '\0'; -} - #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/backend/qr.c b/backend/qr.c index 2c9834bf..44053801 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -94,41 +94,54 @@ static int qr_in_numeric(const unsigned int ddata[], const int length, const int /* Whether in alpha or not. If in alpha, *p_end is set to position after alpha, and *p_cost is set to per-alpha cost. * For GS1, *p_pcent set if 2nd char percent */ static int qr_in_alpha(const unsigned int ddata[], const int length, const int in_posn, - unsigned int *p_end, unsigned int *p_cost, unsigned int *p_pcent, unsigned int gs1) { + unsigned int *p_end, unsigned int *p_cost, unsigned int *p_pcent, unsigned int *p_pccnt, + unsigned int gs1) { + const int last = in_posn + 1 == length; int two_alphas; + /* Attempt to calculate the average 'cost' of using alphanumeric mode in number of bits (times QR_MULT) */ if (in_posn < (int) *p_end) { if (gs1 && *p_pcent) { /* Previous 2nd char was a percent, so allow for second half of doubled-up percent here */ - two_alphas = in_posn < length - 1 && qr_is_alpha(ddata[in_posn + 1], gs1); - *p_cost = two_alphas ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; + two_alphas = !last && qr_is_alpha(ddata[in_posn + 1], gs1); + /* Uneven percents means this will fit evenly in alpha pair */ + *p_cost = two_alphas || !(*p_pccnt & 1) ? 66 /* 11 * QR_MULT */ : 69 /* (11 / 2 + 6) * QR_MULT */; *p_pcent = 0; + } else { + /* As above, uneven percents means will fit in alpha pair */ + *p_cost = !last || !(*p_pccnt & 1) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; } return 1; } - /* Attempt to calculate the average 'cost' of using alphanumeric mode in number of bits (times QR_MULT) */ if (!qr_is_alpha(ddata[in_posn], gs1)) { *p_end = 0; *p_pcent = 0; + *p_pccnt = 0; return 0; } + two_alphas = !last && qr_is_alpha(ddata[in_posn + 1], gs1); + if (gs1 && ddata[in_posn] == '%') { /* Must double-up so counts as 2 chars */ *p_end = in_posn + 1; - *p_cost = 66; /* 11 * QR_MULT */ *p_pcent = 0; + (*p_pccnt)++; + /* Uneven percents means will fit in alpha pair */ + *p_cost = two_alphas || !(*p_pccnt & 1) ? 66 /* 11 * QR_MULT */ : 69 /* (11 / 2 + 6) * QR_MULT */; return 1; } - two_alphas = in_posn < length - 1 && qr_is_alpha(ddata[in_posn + 1], gs1); - *p_end = two_alphas ? in_posn + 2 : in_posn + 1; - *p_cost = two_alphas ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; *p_pcent = two_alphas && gs1 && ddata[in_posn + 1] == '%'; /* 2nd char is percent */ + *p_pccnt += *p_pcent; /* No-op unless `gs1` */ + /* Uneven percents means will fit in alpha pair */ + *p_cost = two_alphas || !(*p_pccnt & 1) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; return 1; } +/*#define QR_DEBUG_DEFINE_MODE*/ /* For debugging costings */ + /* Indexes into qr_mode_types array (and state array) */ #define QR_N 0 /* Numeric */ #define QR_A 1 /* Alphanumeric */ @@ -146,13 +159,14 @@ static const char qr_mode_types[] = { 'N', 'A', 'B', 'K', '\0' }; /* Must be in #define QR_A_END 7 /* Alpha end index */ #define QR_A_COST 8 /* Alpha cost */ #define QR_A_PCENT 9 /* Alpha 2nd char percent (GS1-specific) */ +#define QR_A_PCCNT 10 /* Alpha total percent count (GS1-specific) */ /* Costs set to this for invalid MICROQR modes for versions M1 and M2. * 128 is the max number of data bits for M4-L (ISO/IEC 18004:2015 Table 7) */ #define QR_MICROQR_MAX 774 /* (128 + 1) * QR_MULT */ /* Initial mode costs */ -static unsigned int *qr_head_costs(unsigned int state[10]) { +static unsigned int *qr_head_costs(unsigned int state[11]) { static const unsigned int head_costs[7][QR_NUM_MODES] = { /* N A B K */ { (10 + 4) * QR_MULT, (9 + 4) * QR_MULT, (8 + 4) * QR_MULT, (8 + 4) * QR_MULT, }, /* QR */ @@ -206,10 +220,10 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le * - The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. */ - unsigned int state[10] = { + unsigned int state[11] = { 0 /*N*/, 0 /*A*/, 0 /*B*/, 0 /*K*/, /* Head/switch costs */ 0 /*version*/, - 0 /*numeric_end*/, 0 /*numeric_cost*/, 0 /*alpha_end*/, 0 /*alpha_cost*/, 0 /*alpha_pcent*/ + 0 /*numeric_end*/, 0 /*numeric_cost*/, 0 /*alpha_end*/, 0 /*alpha_cost*/, 0 /*alpha_pcent*/, 0 /*alpha_pccnt*/ }; int m1, m2; @@ -230,6 +244,14 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le * bits needed to encode the entire string prefix of length i, and end in qr_mode_types[j] */ memcpy(prev_costs, qr_head_costs(state), QR_NUM_MODES * sizeof(unsigned int)); + #ifdef QR_DEBUG_DEFINE_MODE + printf(" head"); + for (j = 0; j < QR_NUM_MODES; j++) { + printf(" %c(%c)=%d", qr_mode_types[j], char_modes[j], prev_costs[j]); + } + printf("\n"); + #endif + /* Calculate costs using dynamic programming */ for (i = 0, cm_i = 0; i < length; i++, cm_i += QR_NUM_MODES) { memset(cur_costs, 0, QR_NUM_MODES * sizeof(unsigned int)); @@ -247,7 +269,8 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le cur_costs[QR_N] = prev_costs[QR_N] + state[QR_N_COST]; char_modes[cm_i + QR_N] = 'N'; } - if (qr_in_alpha(ddata, length, i, &state[QR_A_END], &state[QR_A_COST], &state[QR_A_PCENT], gs1)) { + if (qr_in_alpha(ddata, length, i, &state[QR_A_END], &state[QR_A_COST], &state[QR_A_PCENT], + &state[QR_A_PCCNT], gs1)) { cur_costs[QR_A] = prev_costs[QR_A] + (m1 ? QR_MICROQR_MAX : state[QR_A_COST]); char_modes[cm_i + QR_A] = 'A'; } @@ -268,6 +291,13 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le } } + #ifdef QR_DEBUG_DEFINE_MODE + printf(" curr"); + for (j = 0; j < QR_NUM_MODES; j++) { + printf(" %c(%c)=%d", qr_mode_types[j], char_modes[cm_i + j], cur_costs[j]); + } + printf("\n"); + #endif memcpy(prev_costs, cur_costs, QR_NUM_MODES * sizeof(unsigned int)); } @@ -1725,8 +1755,18 @@ INTERNAL int qrcode(struct zint_symbol *symbol, struct zint_seg segs[], const in } } if (autosize != 40) { + /* Save version 40 estimate in case incorrect costings in `qr_define_mode()` lead to its `mode` being better + than current lower version one */ + prev_est_binlen = est_binlen; est_binlen = qr_calc_binlen_segs(autosize, mode, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, debug_print); + if (prev_est_binlen < est_binlen) { /* Shouldn't happen */ + assert(0); /* Not reached (hopefully) */ + /* Defensively use version 40 `mode` to avoid crashes (ticket #300) */ + est_binlen = qr_calc_binlen_segs(40, mode, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, + gs1, debug_print); + assert(est_binlen == prev_est_binlen); + } } /* Now see if the optimised binary will fit in a smaller symbol. */ diff --git a/backend/tests/test_dmatrix.c b/backend/tests/test_dmatrix.c index 98702878..75826c5a 100644 --- a/backend/tests/test_dmatrix.c +++ b/backend/tests/test_dmatrix.c @@ -352,11 +352,11 @@ static void test_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[ZINT_MAX_DATA_LEN]; - testStart("test_large"); + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -415,9 +415,9 @@ static void test_buffer(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_buffer"); + testStartSymbol("test_buffer", &symbol); for (i = 0; i < data_size; i++) { @@ -559,9 +559,9 @@ static void test_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_options"); + testStartSymbol("test_options", &symbol); for (i = 0; i < data_size; i++) { @@ -621,11 +621,11 @@ static void test_reader_init(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; - testStart("test_reader_init"); + testStartSymbol("test_reader_init", &symbol); for (i = 0; i < data_size; i++) { @@ -936,7 +936,7 @@ static void test_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; char cmp_buf[32768]; @@ -945,7 +945,7 @@ static void test_input(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_input"); + testStartSymbol("test_input", &symbol); for (i = 0; i < data_size; i++) { @@ -963,7 +963,8 @@ static void test_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, %s, \"%s\", %s, %d, %d, %d, %d, \"%s\", \"%s\", %d },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_2, + testUtilOption3Name(BARCODE_DATAMATRIX, data[i].option_3), testUtilOutputOptionsName(data[i].output_options), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->rows, symbol->width, data[i].bwipp_cmp, symbol->errtxt, data[i].comment, data[i].expected_diff); @@ -5504,7 +5505,7 @@ static void test_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; char cmp_buf[32768]; @@ -5513,7 +5514,7 @@ static void test_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode"); + testStartSymbol("test_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -5533,7 +5534,7 @@ static void test_encode(const testCtx *const p_ctx) { printf(" /*%3d*/ { %s, %s, %d, %s, %d, %s, \"%s\", %d, %s, %d, %d, %d, \"%s\", %d,\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOutputOptionsName(data[i].output_options), - data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment, data[i].expected_diff); @@ -5800,7 +5801,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; char cmp_buf[32768]; @@ -5809,7 +5810,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode_segs"); + testStartSymbol("test_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -5838,7 +5839,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { printf(" /*%3d*/ { %s, %s, %s, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), - data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, @@ -6935,14 +6936,14 @@ static void test_minimalenc(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; unsigned char binary[2][2200]; int gs1; int binlen; int binlens[2] = {0}; - testStart("test_minimalenc"); + testStartSymbol("test_minimalenc", &symbol); for (i = 0; i < data_size; i++) { diff --git a/backend/tests/test_dotcode.c b/backend/tests/test_dotcode.c index 9b43a31b..38f7a204 100644 --- a/backend/tests/test_dotcode.c +++ b/backend/tests/test_dotcode.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2022 Robin Stuart + Copyright (C) 2019-2023 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -51,11 +51,11 @@ static void test_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[4096]; - testStart("test_large"); + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -119,9 +119,9 @@ static void test_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_options"); + testStartSymbol("test_options", &symbol); for (i = 0; i < data_size; i++) { @@ -212,7 +212,7 @@ static void test_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char cmp_buf[32768]; @@ -221,7 +221,7 @@ static void test_input(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_input"); + testStartSymbol("test_input", &symbol); for (i = 0; i < data_size; i++) { @@ -1079,7 +1079,7 @@ static void test_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char cmp_buf[8192]; @@ -1088,7 +1088,7 @@ static void test_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode"); + testStartSymbol("test_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -1107,7 +1107,8 @@ static void test_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, { %d, %d, \"%s\" }, \"%s\", %d, %s, %d, %d, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_2, + testUtilOption3Name(BARCODE_DOTCODE, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); @@ -1458,7 +1459,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char cmp_buf[8192]; @@ -1467,7 +1468,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode_segs"); + testStartSymbol("test_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -1493,7 +1494,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length; int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length; printf(" /*%3d*/ { %s, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_2, + testUtilOption3Name(BARCODE_DOTCODE, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, @@ -1591,9 +1593,9 @@ static void test_fuzz(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_fuzz"); + testStartSymbol("test_fuzz", &symbol); for (i = 0; i < data_size; i++) { diff --git a/backend/tests/test_gridmtx.c b/backend/tests/test_gridmtx.c index aecd76c4..75837b32 100644 --- a/backend/tests/test_gridmtx.c +++ b/backend/tests/test_gridmtx.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2022 Robin Stuart + Copyright (C) 2019-2023 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -69,11 +69,11 @@ static void test_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[2755 + 1]; - testStart("test_large"); + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -142,9 +142,9 @@ static void test_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_options"); + testStartSymbol("test_options", &symbol); for (i = 0; i < data_size; i++) { @@ -319,11 +319,11 @@ static void test_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; - testStart("test_input"); + testStartSymbol("test_input", &symbol); for (i = 0; i < data_size; i++) { @@ -344,7 +344,8 @@ static void test_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, %s, { %d, %d, \"%s\" }, \"%s\", %s, %d, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOutputOptionsName(data[i].output_options), testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOutputOptionsName(data[i].output_options), + testUtilOption3Name(BARCODE_GRIDMATRIX, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt, data[i].comment); @@ -476,9 +477,9 @@ static void test_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_encode"); + testStartSymbol("test_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -811,11 +812,11 @@ static void test_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; - testStart("test_encode_segs"); + testStartSymbol("test_encode_segs", &symbol); for (i = 0; i < data_size; i++) { diff --git a/backend/tests/test_hanxin.c b/backend/tests/test_hanxin.c index f3703f92..625dd8cf 100644 --- a/backend/tests/test_hanxin.c +++ b/backend/tests/test_hanxin.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2022 Robin Stuart + Copyright (C) 2019-2023 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -71,11 +71,11 @@ static void test_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[7829]; - testStart("test_large"); + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -131,9 +131,9 @@ static void test_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_options"); + testStartSymbol("test_options", &symbol); for (i = 0; i < data_size; i++) { @@ -278,7 +278,7 @@ static void test_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char cmp_buf[32768]; @@ -286,7 +286,7 @@ static void test_input(const testCtx *const p_ctx) { int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_input"); + testStartSymbol("test_input", &symbol); for (i = 0; i < data_size; i++) { @@ -304,7 +304,7 @@ static void test_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, \"%s\", %d, %s, %d, \"%s\", %d, \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOption3Name(BARCODE_HANXIN, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt, data[i].zxingcpp_cmp, data[i].comment); @@ -3256,7 +3256,7 @@ static void test_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; char cmp_buf[32768]; @@ -3264,7 +3264,7 @@ static void test_encode(const testCtx *const p_ctx) { int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode"); + testStartSymbol("test_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -3283,7 +3283,7 @@ static void test_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, \"%s\", %d, %s, %d, %d, \"%s\",\n", i, testUtilInputModeName(data[i].input_mode), data[i].eci, - data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_1, data[i].option_2, testUtilOption3Name(BARCODE_HANXIN, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); @@ -3540,7 +3540,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[8192]; char cmp_buf[32768]; @@ -3548,7 +3548,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_encode_segs"); + testStartSymbol("test_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -3573,7 +3573,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length; printf(" /*%3d*/ { %s, %d, %d, %s, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, \"%s\",\n", i, testUtilInputModeName(data[i].input_mode), - data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_1, data[i].option_2, testUtilOption3Name(BARCODE_HANXIN, data[i].option_3), testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, diff --git a/backend/tests/test_qr.c b/backend/tests/test_qr.c index 9ffc8b0b..e054c9e5 100644 --- a/backend/tests/test_qr.c +++ b/backend/tests/test_qr.c @@ -67,7 +67,7 @@ static void test_qr_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[ZINT_MAX_DATA_LEN]; @@ -78,7 +78,7 @@ static void test_qr_large(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_large"); + testStartSymbol("test_qr_large", &symbol); for (i = 0; i < data_size; i++) { @@ -206,11 +206,11 @@ static void test_qr_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; struct zint_symbol previous_symbol; - testStart("test_qr_options"); + testStartSymbol("test_qr_options", &symbol); for (i = 0; i < data_size; i++) { @@ -425,7 +425,7 @@ static void test_qr_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -434,7 +434,7 @@ static void test_qr_input(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_input"); + testStartSymbol("test_qr_input", &symbol); for (i = 0; i < data_size; i++) { @@ -452,7 +452,8 @@ static void test_qr_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, %d, \"%s\", %d, %d, \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, + testUtilOption3Name(BARCODE_QRCODE, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); @@ -511,34 +512,141 @@ static void test_qr_gs1(const testCtx *const p_ctx) { char *data; int ret; char *expected; + int bwipp_cmp; char *comment; }; struct item data[] = { - /* 0*/ { GS1_MODE, 4, 7 << 8, "[01]12345678901231", 0, "51 04 00 B3 AA 37 DE 87 B1", "N16" }, - /* 1*/ { GS1_MODE | GS1PARENS_MODE, 4, 7 << 8, "(01)12345678901231", 0, "51 04 00 B3 AA 37 DE 87 B1", "N16" }, - /* 2*/ { GS1_MODE, 2, 4 << 8, "[01]04912345123459[15]970331[30]128[10]ABC123", 0, "51 07 40 A7 AC EA 80 15 9E 4F CA 52 D2 D3 84 09 D5 E0 28 FD 82 F0 C0 EC 11 EC 11 EC", "N29 A9" }, - /* 3*/ { GS1_MODE | GS1PARENS_MODE, 2, 4 << 8, "(01)04912345123459(15)970331(30)128(10)ABC123", 0, "51 07 40 A7 AC EA 80 15 9E 4F CA 52 D2 D3 84 09 D5 E0 28 FD 82 F0 C0 EC 11 EC 11 EC", "N29 A9" }, - /* 4*/ { GS1_MODE, 3, -1, "[91]12%[20]12", 0, "52 05 99 60 5F B5 35 80 01 08 00 EC 11", "A10(11)" }, - /* 5*/ { GS1_MODE, 3, 1 << 8, "[91]123%[20]12", 0, "52 06 19 60 5E 2B 76 A0 5A 05 E0 EC 11", "A11(12)" }, - /* 6*/ { GS1_MODE, 3, 6 << 8, "[91]1234%[20]12", 0, "52 06 99 60 5E 22 F6 A6 B0 00 21 00 EC", "A12(13)" }, - /* 7*/ { GS1_MODE, 3, -1, "[91]12345%[20]12", 0, "51 01 F8 F3 A9 48 0F B5 35 80 01 08 00", "N7 A6(7) (same bit count as A13(14))" }, - /* 8*/ { GS1_MODE, 3, 8 << 8, "[91]%%[20]12", 0, "52 05 99 6D A9 B5 35 80 01 08 00 EC 11", "A9(11)" }, - /* 9*/ { GS1_MODE, 3, 6 << 8, "[91]%%%[20]12", 0, "52 06 99 6D A9 B5 36 A6 B0 00 21 00 EC", "A10(13)" }, - /* 10*/ { GS1_MODE, 3, 6 << 8, "[91]A%%%%1234567890123AA%", 0, "52 05 99 63 D1 B5 36 A6 D4 98 40 D1 ED C8 C5 40 C3 20 21 CC DA 80", "A7(11) N13 A3(4)" }, - /* 11*/ { GS1_MODE, 1, -1, "[91]%23%%6789%%%34567%%%%234%%%%%", 0, "(34) 52 17 19 6D A8 17 76 A6 D4 22 A5 C7 6A 6D 4D A8 22 C7 39 61 DA 9B 53 6A 6B 01 17 B5", "A31(46)" }, - /* 12*/ { GS1_MODE, 2, 5 << 8, "[91]ABCDEFGHI[92]ABCDEF", 0, "52 0A 19 63 9A 8A 54 2A E1 6A 06 5C E6 A2 95 0A", "A20(23)" }, + /* 0*/ { GS1_MODE, 4, 7 << 8, "[01]12345678901231", 0, "51 04 00 B3 AA 37 DE 87 B1", 1, "N16" }, + /* 1*/ { GS1_MODE | GS1PARENS_MODE, 4, 7 << 8, "(01)12345678901231", 0, "51 04 00 B3 AA 37 DE 87 B1", 1, "N16" }, + /* 2*/ { GS1_MODE, 2, 4 << 8, "[01]04912345123459[15]970331[30]128[10]ABC123", 0, "51 07 40 A7 AC EA 80 15 9E 4F CA 52 D2 D3 84 09 D5 E0 28 FD 82 F0 C0 EC 11 EC 11 EC", 1, "N29 A9" }, + /* 3*/ { GS1_MODE | GS1PARENS_MODE, 2, 4 << 8, "(01)04912345123459(15)970331(30)128(10)ABC123", 0, "51 07 40 A7 AC EA 80 15 9E 4F CA 52 D2 D3 84 09 D5 E0 28 FD 82 F0 C0 EC 11 EC 11 EC", 1, "N29 A9" }, + /* 4*/ { GS1_MODE, 3, -1, "[91]12%[20]12", 0, "52 05 99 60 5F B5 35 80 01 08 00 EC 11", 1, "A10(11)" }, + /* 5*/ { GS1_MODE, 3, 1 << 8, "[91]123%[20]12", 0, "52 06 19 60 5E 2B 76 A0 5A 05 E0 EC 11", 1, "A11(12)" }, + /* 6*/ { GS1_MODE, 3, 6 << 8, "[91]1234%[20]12", 0, "52 06 99 60 5E 22 F6 A6 B0 00 21 00 EC", 1, "A12(13)" }, + /* 7*/ { GS1_MODE, 3, -1, "[91]12345%[20]12", 0, "51 01 F8 F3 A9 48 0F B5 35 80 01 08 00", 1, "N7 A6(7) (same bit count as A13(14))" }, + /* 8*/ { GS1_MODE, 3, 8 << 8, "[91]%%[20]12", 0, "52 05 99 6D A9 B5 35 80 01 08 00 EC 11", 1, "A9(11)" }, + /* 9*/ { GS1_MODE, 3, 6 << 8, "[91]%%%[20]12", 0, "52 06 99 6D A9 B5 36 A6 B0 00 21 00 EC", 1, "A10(13)" }, + /* 10*/ { GS1_MODE, 3, 6 << 8, "[91]A%%%%1234567890123AA%", 0, "54 07 39 31 41 25 25 25 25 10 34 7B 72 31 50 30 C8 08 73 36 A0 00", 0, "B7 N13 A3(4); BWIPP different encoding (same no. codewords)" }, + /* 11*/ { GS1_MODE, 1, -1, "[91]%23%%6789%%%34567%%%%234%%%%%", 0, "(34) 52 0C 99 6D A8 17 76 A6 D4 22 A5 C7 6A 6D 4D A8 22 C7 38 E8 18 4A 4A 4A 4A 64 66 68", 0, "A19(25) B12; BWIPP different encoding (same no. codewords, less padding)" }, + /* 12*/ { GS1_MODE, 2, 5 << 8, "[91]ABCDEFGHI[92]ABCDEF", 0, "52 0A 19 63 9A 8A 54 2A E1 6A 06 5C E6 A2 95 0A", 1, "A20(23)" }, + /* 13*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%", 0, "54 01 25 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11", 0, "B1; BWIPP different encoding (A2)" }, + /* 14*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%A", 0, "54 02 25 41 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC", 0, "B2; BWIPP different encoding (A3)" }, + /* 15*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%", 0, "54 02 41 25 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC", 0, "B2; BWIPP different encoding (A3)" }, + /* 16*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%AA", 0, "52 02 6D 43 98 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, "A3(4)" }, + /* 17*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%A", 0, "52 02 1E 8D 70 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, "A3(4)" }, + /* 18*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]AA%", 0, "52 02 1C CD A8 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, "A3(4)" }, + /* 19*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%%", 0, "54 02 25 25 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC", 0, "B2; BWIPP different encoding (A4)" }, + /* 20*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%%A", 0, "54 03 25 25 41 00 EC 11 EC 11 EC 11 EC 11 EC 11", 0, "B3; BWIPP different encoding (A5)" }, + /* 21*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%A%", 0, "54 03 25 41 25 00 EC 11 EC 11 EC 11 EC 11 EC 11", 0, "B3; BWIPP different encoding (A5)" }, + /* 22*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%%", 0, "54 03 41 25 25 00 EC 11 EC 11 EC 11 EC 11 EC 11", 0, "B3; BWIPP different encoding (A5)" }, + /* 23*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%AAA", 0, "52 02 ED 43 98 50 00 EC 11 EC 11 EC 11 EC 11 EC", 1, "A4(5)" }, + /* 24*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%AA", 0, "52 02 9E 8D 70 50 00 EC 11 EC 11 EC 11 EC 11 EC", 1, "A4(5)" }, + /* 25*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%AA", 0, "52 02 9E 8D 70 50 00 EC 11 EC 11 EC 11 EC 11 EC", 1, "A4(5)" }, + /* 26*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]AA%A", 0, "52 02 9C CD A8 50 00 EC 11 EC 11 EC 11 EC 11 EC", 1, "A4(5)" }, + /* 27*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]AAA%", 0, "52 02 9C C3 D1 30 00 EC 11 EC 11 EC 11 EC 11 EC", 1, "A4(5)" }, + /* 28*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%%AA", 0, "54 04 25 25 41 41 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A6) (same no. codewords)" }, + /* 29*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]%A%A", 0, "54 04 25 41 25 41 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A6) (same no. codewords)" }, + /* 30*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%%A", 0, "54 04 41 25 25 41 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A6) (same no. codewords)" }, + /* 31*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]A%A%", 0, "54 04 41 25 41 25 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A6) (same no. codewords)" }, + /* 32*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 5 << 8, "[]AA%%", 0, "54 04 41 41 25 25 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A6) (same no. codewords)" }, + /* 33*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAA", 0, "52 03 ED 4D A8 73 0A 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 34*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%AA", 0, "52 03 ED 43 D1 AE 0A 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 35*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%AA", 0, "52 03 9E 8D A9 AE 0A 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 36*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A", 0, "52 03 9E 8D 71 B5 0A 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 37*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%%A", 0, "52 03 9C CD A9 B5 0A 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 38*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%A%", 0, "52 03 9C CD A8 7A 26 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 39*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAA%%", 0, "52 03 9C C3 D1 B5 26 00 EC 11 EC 11 EC 11 EC 11", 1, "A5(7)" }, + /* 40*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%", 0, "54 03 25 25 25 00 EC 11 EC 11 EC 11 EC 11 EC 11", 0, "B3; BWIPP different encoding (A6)" }, + /* 41*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%A", 0, "54 04 25 25 25 41 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A7)" }, + /* 42*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%A%", 0, "54 04 25 25 41 25 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A7)" }, + /* 43*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%", 0, "54 04 25 41 25 25 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A7)" }, + /* 44*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%%", 0, "54 04 41 25 25 25 00 EC 11 EC 11 EC 11 EC 11 EC", 0, "B4; BWIPP different encoding (A7)" }, + /* 45*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AA", 0, "54 05 25 25 25 41 41 00 EC 11 EC 11 EC 11 EC 11", 0, "B5; BWIPP different encoding (A8)" }, + /* 46*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%%%", 0, "54 05 41 41 25 25 25 00 EC 11 EC 11 EC 11 EC 11", 0, "B5; BWIPP different encoding (A8)" }, + /* 47*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAA", 0, "54 06 25 25 25 41 41 41 00 EC 11 EC 11 EC 11 EC", 0, "B6; BWIPP different encoding (A9)" }, + /* 48*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A%", 0, "54 06 41 25 41 25 41 25 00 EC 11 EC 11 EC 11 EC", 0, "B6; BWIPP different encoding (A9)" }, + /* 49*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAA", 0, "52 04 6D 4D A8 73 0E 60 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 50*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%AAA", 0, "52 04 6D 43 D1 AE 0E 60 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 51*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AA%AA", 0, "52 04 6D 43 99 B5 0E 60 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 52*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAA%A", 0, "52 04 6D 43 98 7A 35 C0 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 53*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAA%", 0, "52 04 6D 43 98 73 36 A0 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 54*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%AAA", 0, "52 04 1E 8D A9 AE 0E 60 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 55*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%%AA", 0, "52 04 1C CD A9 B5 0E 60 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 56*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAA%%A", 0, "52 04 1C C3 D1 B5 35 C0 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 57*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAA%%", 0, "52 04 1C C3 99 B5 36 A0 00 EC 11 EC 11 EC 11 EC", 1, "A6(8)" }, + /* 58*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAAA", 0, "52 04 ED 4D A8 73 0E 61 40 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 59*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%AAAA", 0, "52 04 ED 43 D1 AE 0E 61 40 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 60*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AA%AAA", 0, "52 04 ED 43 99 B5 0E 61 40 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 61*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAA%AA", 0, "52 04 ED 43 98 7A 35 C1 40 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 62*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAA%A", 0, "52 04 ED 43 98 73 36 A1 40 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 63*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAAA%", 0, "52 04 ED 43 98 73 0F 44 C0 EC 11 EC 11 EC 11 EC", 1, "A7(9)" }, + /* 64*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAAAA", 0, "52 05 ED 4D A9 B5 0E 61 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 65*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%A%AAAA", 0, "52 05 ED 4D A8 7A 35 C1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 66*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AA%AAA", 0, "52 05 ED 4D A8 73 36 A1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 67*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAA%AA", 0, "52 05 ED 4D A8 73 0F 46 B8 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 68*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAA%A", 0, "52 05 ED 4D A8 73 0E 66 D4 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 69*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAAA%", 0, "52 05 ED 4D A8 73 0E 61 E8 98 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 70*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%AAAA", 0, "52 05 ED 43 D1 B5 35 C1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 71*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AA%%AAA", 0, "52 05 ED 43 99 B5 36 A1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 72*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAA%%AA", 0, "52 05 ED 43 98 7A 36 A6 B8 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 73*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAA%%A", 0, "52 05 ED 43 98 73 36 A6 D4 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 74*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAAA%%", 0, "52 05 ED 43 98 73 0F 46 D4 98 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 75*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%%AAAA", 0, "52 05 9E 8D A9 B5 35 C1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 76*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%%%AAA", 0, "52 05 9C CD A9 B5 36 A1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 77*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAA%%%AA", 0, "52 05 9C C3 D1 B5 36 A6 B8 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 78*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAA%%%A", 0, "52 05 9C C3 99 B5 36 A6 D4 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 79*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAAA%%%", 0, "52 05 9C C3 98 7A 36 A6 D4 98 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 80*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A%AA", 0, "52 05 9E 8D 71 B5 0F 46 B8 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 81*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%AA%A", 0, "52 05 9E 8D 71 B5 0E 66 D4 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 82*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%AAA%", 0, "52 05 9E 8D 71 B5 0E 61 E8 98 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 83*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%A%AAA", 0, "52 05 ED 43 D1 AE 36 A1 CC 28 00 EC 11 EC 11 EC", 1, "A8(11)" }, + /* 84*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%%AAAAAA", 0, "52 07 6D 4D A9 B5 36 A1 CC 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 85*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%A%AAAAA", 0, "52 07 6D 4D A9 B5 0F 46 B8 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 86*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AA%AAAA", 0, "52 07 6D 4D A9 B5 0E 66 D4 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 87*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAA%AAA", 0, "52 07 6D 4D A9 B5 0E 61 E8 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /* 88*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAAA%AA", 0, "52 07 6D 4D A9 B5 0E 61 CC DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 89*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAAAA%A", 0, "52 07 6D 4D A9 B5 0E 61 CC 3D 1A E0 00 EC 11 EC", 1, "A10(14)" }, + /* 90*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%%AAAAAA%", 0, "52 07 6D 4D A9 B5 0E 61 CC 39 9B 50 00 EC 11 EC", 1, "A10(14)" }, + /* 91*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%A%%AAAAA", 0, "52 07 6D 4D A8 7A 36 A6 B8 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 92*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AA%%AAAA", 0, "52 07 6D 4D A8 73 36 A6 D4 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 93*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAA%%AAA", 0, "52 07 6D 4D A8 73 0F 46 D4 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /* 94*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAA%%AA", 0, "52 07 6D 4D A8 73 0E 66 D4 DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 95*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAAA%%A", 0, "52 07 6D 4D A8 73 0E 61 E8 DA 9A E0 00 EC 11 EC", 1, "A10(14)" }, + /* 96*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%%AAAAAA%%", 0, "52 07 6D 4D A8 73 0E 61 CC DA 9B 50 00 EC 11 EC", 1, "A10(14)" }, + /* 97*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%%AAAAA", 0, "52 07 6D 43 D1 B5 36 A6 B8 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 98*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AA%%%AAAA", 0, "52 07 6D 43 99 B5 36 A6 D4 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /* 99*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAA%%%AAA", 0, "52 07 6D 43 98 7A 36 A6 D4 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /*100*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAA%%%AA", 0, "52 07 6D 43 98 73 36 A6 D4 DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*101*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAAA%%%A", 0, "52 07 6D 43 98 73 0F 46 D4 DA 9A E0 00 EC 11 EC", 1, "A10(14)" }, + /*102*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%AAAAAA%%%", 0, "52 07 6D 43 98 73 0E 66 D4 DA 9B 50 00 EC 11 EC", 1, "A10(14)" }, + /*103*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%%%AAAAA", 0, "52 07 1E 8D A9 B5 36 A6 B8 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*104*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AA%%%%AAAA", 0, "52 07 1C CD A9 B5 36 A6 D4 39 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*105*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAA%%%%AAA", 0, "52 07 1C C3 D1 B5 36 A6 D4 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /*106*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAA%%%%AA", 0, "52 07 1C C3 99 B5 36 A6 D4 DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*107*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAAA%%%%A", 0, "52 07 1C C3 98 7A 36 A6 D4 DA 9A E0 00 EC 11 EC", 1, "A10(14)" }, + /*108*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]AAAAAA%%%%", 0, "52 07 1C C3 98 73 36 A6 D4 DA 9B 50 00 EC 11 EC", 1, "A10(14)" }, + /*109*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A%A%AA", 0, "52 07 1E 8D 71 B5 0F 46 B8 DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*110*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A%AA%A", 0, "52 07 1E 8D 71 B5 0F 46 B8 3D 1A E0 00 EC 11 EC", 1, "A10(14)" }, + /*111*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%A%A%AAA%", 0, "52 07 1E 8D 71 B5 0F 46 B8 39 9B 50 00 EC 11 EC", 1, "A10(14)" }, + /*112*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%A%A%AAA", 0, "52 07 6D 43 D1 AE 36 A1 E8 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /*113*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]A%%AA%A%AA", 0, "52 07 1E 8D A9 AE 0F 46 B8 DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*114*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%AA%AAA", 0, "52 07 6D 43 D1 B5 35 C1 E8 D7 07 30 00 EC 11 EC", 1, "A10(14)" }, + /*115*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%AAA%AA", 0, "52 07 6D 43 D1 B5 35 C1 CC DA 87 30 00 EC 11 EC", 1, "A10(14)" }, + /*116*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%AAAA%A", 0, "52 07 6D 43 D1 B5 35 C1 CC 3D 1A E0 00 EC 11 EC", 1, "A10(14)" }, + /*117*/ { GS1_MODE | GS1NOCHECK_MODE, 2, 3 << 8, "[]%A%%AAAAA%", 0, "52 07 6D 43 D1 B5 35 C1 CC 39 9B 50 00 EC 11 EC", 1, "A10(14)" }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; char cmp_msg[1024]; int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_gs1"); + testStartSymbol("test_qr_gs1", &symbol); for (i = 0; i < data_size; i++) { @@ -555,14 +663,16 @@ static void test_qr_gs1(const testCtx *const p_ctx) { assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { - printf(" /*%3d*/ { %s, %d, %d, \"%s\", %s, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_3, - testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].comment); + printf(" /*%3d*/ { %s, %d, %s, \"%s\", %s, \"%s\", %d, \"%s\" },\n", + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, + testUtilOption3Name(BARCODE_QRCODE, data[i].option_3), + testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), + symbol->errtxt, data[i].bwipp_cmp, data[i].comment); } else { assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, data[i].option_3, debug)) { - if (0 /*!data[i].bwipp_cmp*/) { + if (!data[i].bwipp_cmp) { if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); } else { char modules_dump[177 * 177 + 1]; @@ -575,6 +685,21 @@ static void test_qr_gs1(const testCtx *const p_ctx) { i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); } } + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { + if (0 /*!data[i].zxingcpp_cmp*/) { + if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not ZXing-C++ compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } else { + int cmp_len, ret_len; + char modules_dump[177 * 177 + 1]; + 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, 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); @@ -630,7 +755,7 @@ static void test_qr_optimize(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -639,7 +764,7 @@ static void test_qr_optimize(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_optimize"); + testStartSymbol("test_qr_optimize", &symbol); for (i = 0; i < data_size; i++) { @@ -4129,7 +4254,7 @@ static void test_qr_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -4138,7 +4263,7 @@ static void test_qr_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_encode"); + testStartSymbol("test_qr_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -4160,7 +4285,7 @@ static void test_qr_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %d, %s, %d, %d, %d, \"%s\",\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), - data[i].eci, data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].eci, data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); @@ -4450,7 +4575,7 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -4459,7 +4584,7 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_qr_encode_segs"); + testStartSymbol("test_qr_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -4487,7 +4612,7 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length; printf(" /*%3d*/ { %s, %s, %d, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), - data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, @@ -4804,11 +4929,11 @@ static void test_microqr_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; struct zint_symbol previous_symbol; - testStart("test_microqr_options"); + testStartSymbol("test_microqr_options", &symbol); for (i = 0; i < data_size; i++) { @@ -4912,7 +5037,7 @@ static void test_microqr_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -4921,7 +5046,7 @@ static void test_microqr_input(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_microqr_input"); + testStartSymbol("test_microqr_input", &symbol); for (i = 0; i < data_size; i++) { @@ -4939,7 +5064,8 @@ static void test_microqr_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, \"%s\", %s, \"%s\", %d, %d, \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, + testUtilOption3Name(BARCODE_MICROQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); } else { @@ -5034,7 +5160,7 @@ static void test_microqr_padding(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -5043,7 +5169,7 @@ static void test_microqr_padding(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_microqr_padding"); + testStartSymbol("test_microqr_padding", &symbol); for (i = 0; i < data_size; i++) { @@ -5124,7 +5250,7 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { /* 5*/ { UNICODE_MODE, 1, 4, -1, "01a", 0, "43 30 31 61 00 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, 1, "B3" }, /* 6*/ { UNICODE_MODE, 1, -1, -1, "こんwa、αβ", 0, "46 82 B1 82 F1 77 61 66 00 10 FF 88 00 00 EC 11", 1, 1, "B6 K3" }, /* 7*/ { UNICODE_MODE, 1, -1, -1, "こんにwa、αβ", 0, "66 13 10 B8 85 25 09 DD 85 98 00 43 FE 20 00 00", 1, 1, "K3 B2 K3" }, - /* 8*/ { UNICODE_MODE, 1, 3, -1, "こんAB123\177", 0, "D0 4C 42 E2 91 CD 06 3D C2 FE 00", 0, 1, "K2 A2 N3 B1; BWIPP different encodation (K2 A5 B1)" }, + /* 8*/ { UNICODE_MODE, 1, 3, -1, "こんAB123\177", 0, "D0 4C 42 E2 A9 CD 05 E1 C2 FE 00", 1, 1, "K2 A5 B1" }, /* 9*/ { UNICODE_MODE, 1, 4, -1, "こんAB123\177", 0, "64 13 10 B8 92 9C D0 5E 1A 0B F8 00 EC 11 EC 11", 1, 1, "K2 A5 B1" }, /* 10*/ { DATA_MODE, 1, -1, -1, "\223\137", 0, "8A 4D 7C 00 EC 11 EC 11 EC 11 00", 0, 0, "B2; BWIPP uses Kanji (ZINT_FULL_MULTIBYTE) mode, see below); ZXing-C++ test can't handle DATA_MODE for certain inputs" }, /* 11*/ { DATA_MODE, 1, -1, ZINT_FULL_MULTIBYTE, "\223\137", 0, "CB 67 C0 00 EC 11 EC 11 EC 11 00", 1, 1, "K1" }, @@ -5132,7 +5258,7 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -5141,7 +5267,7 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_microqr_optimize"); + testStartSymbol("test_microqr_optimize", &symbol); for (i = 0; i < data_size; i++) { @@ -5159,7 +5285,8 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, \"%s\", %d, %d, \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_MICROQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); } else { @@ -6166,7 +6293,7 @@ static void test_microqr_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -6175,7 +6302,7 @@ static void test_microqr_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_microqr_encode"); + testStartSymbol("test_microqr_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -6191,7 +6318,8 @@ static void test_microqr_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, %d, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_MICROQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); @@ -6332,11 +6460,11 @@ static void test_upnqr_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; - testStart("test_upnqr_input"); + testStartSymbol("test_upnqr_input", &symbol); for (i = 0; i < data_size; i++) { @@ -6865,7 +6993,7 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -6876,7 +7004,7 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { #endif int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_upnqr_encode"); + testStartSymbol("test_upnqr_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -6892,7 +7020,8 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_UPNQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment); @@ -7472,11 +7601,11 @@ static void test_rmqr_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[ZINT_MAX_DATA_LEN]; - testStart("test_rmqr_large"); + testStartSymbol("test_rmqr_large", &symbol); for (i = 0; i < data_size; i++) { @@ -7602,9 +7731,9 @@ static void test_rmqr_options(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; - testStart("test_rmqr_options"); + testStartSymbol("test_rmqr_options", &symbol); for (i = 0; i < data_size; i++) { @@ -7770,7 +7899,7 @@ static void test_rmqr_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -7778,7 +7907,7 @@ static void test_rmqr_input(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - testStart("test_rmqr_input"); + testStartSymbol("test_rmqr_input", &symbol); for (i = 0; i < data_size; i++) { @@ -7797,7 +7926,7 @@ static void test_rmqr_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, \"%s\", %s, %d, \"%s\", %d, \"%s\" },\n", i, testUtilInputModeName(data[i].input_mode), data[i].eci, - data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + data[i].option_1, data[i].option_2, testUtilOption3Name(BARCODE_RMQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt, data[i].bwipp_cmp, data[i].comment); @@ -7847,22 +7976,22 @@ static void test_rmqr_gs1(const testCtx *const p_ctx) { /* 2*/ { GS1_MODE, "[01]04912345123459[15]970331[30]128[10]ABC123", 0, "A5 D0 29 EB 3A A0 05 67 93 F2 94 B4 B4 E2 4E AF 01 47 EC 17 86", "N29 A9" }, /* 3*/ { GS1_MODE | GS1PARENS_MODE, "(01)04912345123459(15)970331(30)128(10)ABC123", 0, "A5 D0 29 EB 3A A0 05 67 93 F2 94 B4 B4 E2 4E AF 01 47 EC 17 86", "N29 A9" }, /* 4*/ { GS1_MODE, "[91]12%[20]12", 0, "A4 9C 79 32 25 1D 24 32 48 00 EC 11", "N4 B2 N4" }, - /* 5*/ { GS1_MODE, "[91]123%[20]12", 0, "A4 BC 79 74 3D A9 31 21 92 40 EC 11", "N5 A2 N4" }, + /* 5*/ { GS1_MODE, "[91]123%[20]12", 0, "A4 BC 79 76 44 A3 A4 86 49 00 EC 11", "N5 B2 N4" }, /* 6*/ { GS1_MODE, "[91]1234%[20]12", 0, "A4 DC 79 D4 C8 94 74 90 C9 20 EC 11", "N6 B2 N4" }, - /* 7*/ { GS1_MODE, "[91]12345%[20]12", 0, "A4 FC 79 D4 A8 7B 52 62 43 24 80 EC", "N7 A2(3) N4" }, + /* 7*/ { GS1_MODE, "[91]12345%[20]12", 0, "A4 FC 79 D4 AC 89 47 49 0C 92 00 EC", "N7 B2 N4" }, /* 8*/ { GS1_MODE, "[91]1A%[20]12", 0, "A8 E6 58 1B ED 49 89 0C 92 00 EC 11", "A6(7) N4" }, /* 9*/ { GS1_MODE, "[91]%%[20]12", 0, "A4 56 D9 92 92 8E 92 19 24 00 EC 11", "N2 B3 N4" }, /* 10*/ { GS1_MODE, "[91]%%%[20]12", 0, "A4 56 DA 12 92 92 8E 92 19 24 00 EC", "N2 B4 N4" }, - /* 11*/ { GS1_MODE, "[91]A%%%%12345678A%A", 0, "A8 A6 58 F4 4C C6 4A 4A 4A 48 1E DC 89 C8 87 A3 5C 00 EC", "A4(5) B3 N8 A3(4)" }, - /* 12*/ { GS1_MODE, "[91]%23%%6789%%%34567%%%%234%%%%%", 0, "(33) AA 63 2D B5 02 EE D4 DA 84 54 B8 ED 4D A9 B5 04 58 E7 2C 3B 53 6A 6D 4D 60 22 F6 A3", "A27(38) B4" }, + /* 11*/ { GS1_MODE, "[91]A%%%%12345678A%A", 0, "AC E7 26 28 24 A4 A4 A4 A4 81 ED C8 9C 88 7A 35 C0 EC 11", "B7 N8 A3(4)" }, + /* 12*/ { GS1_MODE, "[91]%23%%6789%%%34567%%%%234%%%%%", 0, "(33) A9 43 2D B5 02 EE D4 DA 84 54 B8 ED 4D A9 B5 08 55 66 1B 30 94 94 94 94 C8 CC D0 94", "A14(20) N5 B12" }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; - testStart("test_rmqr_gs1"); + testStartSymbol("test_rmqr_gs1", &symbol); for (i = 0; i < data_size; i++) { @@ -7915,7 +8044,7 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { /* 7*/ { UNICODE_MODE, 4, 11, "0123A", 0, "28 06 1A 12 80", 1, "N4 A1 (nayuki.io - alpha/numeric)" }, /* 8*/ { UNICODE_MODE, 4, 11, "0a", 0, "68 C1 84 00 EC", 1, "B2 (nayuki.io - numeric/byte)" }, /* 9*/ { UNICODE_MODE, 4, 11, "01a", 0, "24 05 96 10 EC", 1, "N2 B1 (nayuki.io - numeric/byte)" }, - /* 10*/ { UNICODE_MODE, 4, 11, "ABCa", 0, "71 05 09 0D 84", 1, "B4 (nayuki.io - alphanumeric/byte)" }, + /* 10*/ { UNICODE_MODE, 4, 11, "ABCa", 0, "46 73 4C 65 84", 0, "A3 B1 (nayuki.io - alphanumeric/byte); BWIPP different encodation (B4)" }, /* 11*/ { UNICODE_MODE, 2, 11, "ABCDa", 0, "48 73 51 4B 2C 20 EC", 1, "A4 B1 (same bits as B5)" }, /* 12*/ { UNICODE_MODE, 2, 24, "THE SQUARE ROOT OF 2 IS 1.41421356237309504880168872420969807856967187537694807317667973799", 0, "(48) 46 A9 52 9A A0 D5 42 66 E6 F8 A1 4F 62 3E 56 CC D4 40 2B 98 2C F1 AB 19 2E A2 F8 61", 1, " A26 N65 (nayuki.io - alpha/numeric)" }, /* 13*/ { UNICODE_MODE, 2, 21, "Golden ratio φ = 1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374......", ZINT_WARN_NONCOMPLIANT, "Warning (73) 65 11 DB DB 19 19 5B 88 1C 98 5D 1A 5B C8 20 F4 C8 0F 48 0C 4B 8B 24 D4 10 FB 97 6E", 1, "B20 N100 A6 (nayuki.io - alpha/numeric/byte)" }, @@ -7930,7 +8059,7 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -7938,7 +8067,7 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - testStart("test_rmqr_optimize"); + testStartSymbol("test_rmqr_optimize", &symbol); for (i = 0; i < data_size; i++) { @@ -8371,7 +8500,7 @@ static void test_rmqr_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -8379,7 +8508,7 @@ static void test_rmqr_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - testStart("test_rmqr_encode"); + testStartSymbol("test_rmqr_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -8502,21 +8631,21 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { }, /* 4*/ { UNICODE_MODE, 2, 32, -1, { { TU("Google Pixel 4a 128 GB Black;price:$439.97"), -1, 3 }, { TU("Google 谷歌 Pixel 4a 128 GB黑色;零售价:¥3149.79"), -1, 29 }, { TU("Google Pixel 4a 128 GB Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 17, 139, 0, "AIM ITS/04-023:2022 Annex A example (shortened); BWIPP different encodation", "1111111010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101010111" - "1000001001000010100111001110100000111100110111111110001010100010000110011100101000101101010100111001001101110110110010000011110000101100101" - "1011101011101011111110110011100101100111101000001011111111110000100000111001000110111011000011100011000000100011101101100100110100110011011" - "1011101001001110000110100100001111011110111110111101000000100101001111110100111010000000011000101101110100000100011001000010001010101111110" - "1011101000010000111010100101101000100010100100110100011110111110001100101010001111110110111000000000101011100001101000001000110000000110111" - "1000001000001001100011001110100010110001011011011100110000111111011101011110010000000000000010001110010111000010001001110111010101011000110" - "1111111010100010010100110101101010100010001110001000100100011111111001000000111011111000110011111010000011011111100111011001000000011010001" - "0000000010010110010000100000000010101010110111110011010010110001100100001000010011000000110101111100010001000000100101100111011000011011110" - "1101110011111001110010000111111111101100100101001110001111101110010110101100001110110110001110100100111100000111111011110100100101011111001" - "0111111100100011001110011010010100110111101101010111000011001111100011011100001100100110011110110101111010101100010101100000010010110101000" - "1011000010101000110000001001010011101001100001111011001100010011011010010000101101110011000011010011011111110101101101100101110101100001001" - "0001110000010011000000110000010111111010010001010100100000101010000111111001110000000101100101110001010001010010011010001110101101111011100" - "1000101101011001001010000001111011100111100000100110101100101100110100100101001101110111101001100111001101111001111010001011011000110111111" - "0110100001110101010110010010100000111110011101011100100010111011000010010110001010000001001001001111000010011100111110010011000110100110001" - "1001000001100110110011100011111101010111100110100101011110010011101010100011101001111010100111010100110100011111110111100101000101010110101" - "1010011110111011011111000010111011001001010001011111011011101000100101110000010011101110110100011010110111010110110011110110000001000110001" + "1000001001000010110111101110110000000110010001001010001010100010000110011100101000101101010100111001001101110110110010000011110000111000101" + "1011101011100111011110110011110001010110001000110011111111110000100000111001000110111011000001100011000000100011101101100100110100110011011" + "1011101001001010011100110110001011111110101111101101000001100101001111110100111010000000011000111101110100000100011001000010001010111100110" + "1011101000001100010010010011011111000001100111100100011100111110001100101010001111111110111000000000101011100001101000001000111100110110111" + "1000001000000011110001010010001001010011011010000100110000111111011101011110010000001100000110101110010111000010001001110111011101111000110" + "1111111010000000010010011101001100101100001010000000000100011111111001000000110011111000111011111010000011011111100111011010000100011000001" + "0000000010011100010100010000111011010000111011111011010010110001100100001000011110000000010001111100010001000000100101100101011000011011110" + "1101110011110000010101110111110111001010010101001110011111101110010110101100100110110100101110100100111100000111111011110100100101011111001" + "0101110111101001110110001110010101111100111101010111000011001111100011011100001001100111001100110101111010101100010101100100010010110101000" + "1000011000101010000011100001100000010101000010001000001100010011011010010000101001110011000011010011011111110101101101101101000101100001001" + "0000110000010010100101011100100001111010010001100100100000101010000111111001110010000101100100111001010001010010011010001110101101111011100" + "1110010111111001100011110101010001100011101010001110101100101100110100100101001101110111101001100111001101111001111010001011111000110111111" + "0100001101110100010111001110101111111010001111100000100010111011000010010110001010000001000001001111000010011100111110010011000111100110001" + "1100011010000101111101101111111111010011001010111001011110010011101010100011101001111010100111010100110100011111110111100101000111010110101" + "1010011110100110011111000010111010001000100111010111011011101000100101110000010011101110110100011010110111010110110011110110000001000110001" "1110101010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101011111" }, /* 5*/ { DATA_MODE, 4, 3, -1, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 7, 77, 1, "Standard example + extra seg, data mode", @@ -8540,7 +8669,7 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[4096]; char cmp_buf[32768]; @@ -8549,7 +8678,7 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ - testStart("test_rmqr_encode_segs"); + testStartSymbol("test_rmqr_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -8631,6 +8760,49 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { testFinish(); } +/* #300 Andre Maute */ +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; + char *data; + int length; + int ret; + int bwipp_cmp; + char *comment; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + struct item data[] = { + /* 0*/ { BARCODE_QRCODE, GS1_MODE | GS1NOCHECK_MODE, -1, -1, "[]CCCCCLLLLLLLLLLLLLLLLLLLLLCCCCCCCC@CCCCCCCCCCCCCCCCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLLLLLLLLLLL000000032861710*383556LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL155816162LLLLLCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLL)!1661055777[723]T5", -1, 0, 1, "" }, /* #300 (#14), Andre Maute */ + }; + int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol("test_fuzz", &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, -1 /*output_options*/, data[i].data, data[i].length, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) 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); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -8660,6 +8832,8 @@ int main(int argc, char *argv[]) { { "test_rmqr_optimize", test_rmqr_optimize }, { "test_rmqr_encode", test_rmqr_encode }, { "test_rmqr_encode_segs", test_rmqr_encode_segs }, + + { "test_fuzz", test_fuzz }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_ultra.c b/backend/tests/test_ultra.c index e0c48f54..be8184a2 100644 --- a/backend/tests/test_ultra.c +++ b/backend/tests/test_ultra.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2022 Robin Stuart + Copyright (C) 2020-2023 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -86,11 +86,11 @@ static void test_large(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char data_buf[ZINT_MAX_DATA_LEN + 1]; - testStart("test_large"); + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -141,11 +141,11 @@ static void test_reader_init(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; - testStart("test_reader_init"); + testStartSymbol("test_reader_init", &symbol); for (i = 0; i < data_size; i++) { @@ -163,7 +163,8 @@ static void test_reader_init(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), + testUtilOption3Name(BARCODE_ULTRA, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { @@ -266,11 +267,11 @@ static void test_input(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; - testStart("test_input"); + testStartSymbol("test_input", &symbol); for (i = 0; i < data_size; i++) { @@ -293,7 +294,8 @@ static void test_input(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %s, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_ULTRA, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].comment); } else { @@ -776,7 +778,7 @@ static void test_encode(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, length, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char bwipp_buf[32768]; @@ -784,7 +786,7 @@ static void test_encode(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - testStart("test_encode"); + testStartSymbol("test_encode", &symbol); for (i = 0; i < data_size; i++) { @@ -803,7 +805,8 @@ static void test_encode(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %s, %d, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_ULTRA, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); @@ -1017,7 +1020,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { }; int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; - struct zint_symbol *symbol; + struct zint_symbol *symbol = NULL; char escaped[1024]; char bwipp_buf[32768]; @@ -1025,7 +1028,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - testStart("test_encode_segs"); + testStartSymbol("test_encode_segs", &symbol); for (i = 0; i < data_size; i++) { @@ -1051,7 +1054,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length; int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length; printf(" /*%3d*/ { %s, %d, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", - i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3), + i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, + testUtilOption3Name(BARCODE_ULTRA, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 9cc8d718..ec588bfe 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -522,30 +522,43 @@ const char *testUtilInputModeName(int input_mode) { } /* Pretty name for option 3 */ -const char *testUtilOption3Name(int option_3) { +const char *testUtilOption3Name(int symbology, int option_3) { static char buffer[64]; const char *name = NULL; const unsigned int high_byte = option_3 == -1 ? 0 : (option_3 >> 8) & 0xFF; - if ((option_3 & 0x7F) == DM_SQUARE) { - if ((option_3 & DM_ISO_144) == DM_ISO_144) { - name = "DM_SQUARE | DM_ISO_144"; + if (symbology == BARCODE_DATAMATRIX || symbology == BARCODE_HIBC_DM) { + if ((option_3 & 0x7F) == DM_SQUARE) { + if ((option_3 & DM_ISO_144) == DM_ISO_144) { + name = "DM_SQUARE | DM_ISO_144"; + } else { + name = "DM_SQUARE"; + } + } else if ((option_3 & 0x7F) == DM_DMRE) { + if ((option_3 & DM_ISO_144) == DM_ISO_144) { + name = "DM_DMRE | DM_ISO_144"; + } else { + name = "DM_DMRE"; + } + } else if ((option_3 & DM_ISO_144) == DM_ISO_144) { + name = "DM_ISO_144"; } else { - name = "DM_SQUARE"; + name = (option_3 & 0xFF) ? "-1" : "0"; } - } else if ((option_3 & 0x7F) == DM_DMRE) { - if ((option_3 & DM_ISO_144) == DM_ISO_144) { - name = "DM_DMRE | DM_ISO_144"; + } else if (symbology == BARCODE_QRCODE || symbology == BARCODE_HIBC_QR || symbology == BARCODE_MICROQR + || symbology == BARCODE_RMQR || symbology == BARCODE_GRIDMATRIX || symbology == BARCODE_HANXIN) { + if ((option_3 & 0xFF) == ZINT_FULL_MULTIBYTE) { + name = "ZINT_FULL_MULTIBYTE"; } else { - name = "DM_DMRE"; + name = (option_3 & 0xFF) ? "-1" : "0"; + } + } else if (symbology == BARCODE_ULTRA) { + if ((option_3 & 0xFF) == ULTRA_COMPRESSION) { + name = "ULTRA_COMPRESSION"; + } else { + name = (option_3 & 0xFF) ? "-1" : "0"; } - } else if ((option_3 & DM_ISO_144) == DM_ISO_144) { - name = "DM_ISO_144"; - } else if ((option_3 & 0xFF) == ZINT_FULL_MULTIBYTE) { - name = "ZINT_FULL_MULTIBYTE"; - } else if ((option_3 & 0xFF) == ULTRA_COMPRESSION) { - name = "ULTRA_COMPRESSION"; } else { if (option_3 != -1 && (option_3 & 0xFF) != 0) { fprintf(stderr, "testUtilOption3Name: unknown value (%d)\n", option_3); diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 375c277d..13adfa81 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -138,7 +138,7 @@ int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, const char *testUtilBarcodeName(int symbology); const char *testUtilErrorName(int error_number); const char *testUtilInputModeName(int input_mode); -const char *testUtilOption3Name(int option_3); +const char *testUtilOption3Name(int symbology, int option_3); const char *testUtilOutputOptionsName(int output_options); int testUtilDAFTConvert(const struct zint_symbol *symbol, char *buffer, const int buffer_size);