diff --git a/ChangeLog b/ChangeLog index 9de508ad..474a811d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -119,6 +119,8 @@ Bugs byte-blocks > 11-bit limit - library: fix 21-bit Unicode conversion in `escape_char_process()`; fix restricting escaped data length by using de-escaped length to check +- CODEONE: fix out-of-bounds crash in `c1_c40text_cnt()`, ticket #300, props + Andre Maute Version 2.12.0 (2022-12-12) diff --git a/backend/code1.c b/backend/code1.c index 57fb4705..128974a5 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -447,6 +447,10 @@ static int c1_c40text_cnt(const int current_mode, const int gs1, unsigned char i return 2; } cnt = 1; + if (input & 0x80) { + cnt += 2; + input -= 128; + } if ((current_mode == C1_C40 && c40_shift[input]) || (current_mode == C1_TEXT && text_shift[input])) { cnt += 1; } diff --git a/backend/tests/test_code1.c b/backend/tests/test_code1.c index 04a64824..aaedc75d 100644 --- a/backend/tests/test_code1.c +++ b/backend/tests/test_code1.c @@ -3356,16 +3356,24 @@ static void test_fuzz(const testCtx *const p_ctx) { char *data; int length; int ret; + int bwipp_cmp; + char *comment; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { "3333P33B\035333V3333333333333\0363", -1, 0 }, /* #181 Nico Gunkel, OSS-Fuzz */ - /* 1*/ { "{{-06\024755712162106130000000829203983\377", -1, 0 }, /* #232 Jan Schrewe, CI-Fuzz, out-of-bounds in is_last_single_ascii() sp + 1 */ + /* 0*/ { "3333P33B\035333V3333333333333\0363", -1, 0, 1, "" }, /* #181 Nico Gunkel, OSS-Fuzz */ + /* 1*/ { "{{-06\024755712162106130000000829203983\377", -1, 0, 1, "" }, /* #232 Jan Schrewe, CI-Fuzz, out-of-bounds in is_last_single_ascii() sp + 1 */ + /* 2*/ { "\000\000\000\367\000\000\000\000\000\103\040\000\000\244\137\140\140\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\165\060\060\060\060\061\060\060\114\114\060\010\102\102\102\102\102\102\102\102\057\102\100\102\057\233\100\102", 60, 0, 1, "" }, /* #300 (#4) Andre Maute */ }; int data_size = ARRAY_SIZE(data); int i, length, ret; struct zint_symbol *symbol; + char bwipp_buf[32768]; + char bwipp_msg[1024]; + + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ + testStart("test_fuzz"); for (i = 0; i < data_size; i++) { @@ -3383,6 +3391,23 @@ static void test_fuzz(const testCtx *const p_ctx) { 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); + if (ret < ZINT_ERROR) { + if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { + 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[4096]; + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + + ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, modules_dump); + assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, modules_dump); + } + } + } + ZBarcode_Delete(symbol); } diff --git a/backend/tests/tools/run_bwipp_tests.sh b/backend/tests/tools/run_bwipp_tests.sh index 768ec939..dcf4ae03 100755 --- a/backend/tests/tools/run_bwipp_tests.sh +++ b/backend/tests/tools/run_bwipp_tests.sh @@ -25,6 +25,7 @@ run_bwipp_test "test_codablock" "encode" run_bwipp_test "test_code" "encode" run_bwipp_test "test_code1" "encode" run_bwipp_test "test_code1" "encode_segs" +run_bwipp_test "test_code1" "fuzz" run_bwipp_test "test_code128" "input" run_bwipp_test "test_code128" "encode" run_bwipp_test "test_code16k" "input"