From 62995f18d240d027454d6adf8788e4a5e35096aa Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 26 Mar 2020 09:35:04 +0000 Subject: [PATCH] #181 OSS-Fuzz UPC/EAN fix, allow max 6 chars add-on in ean_leading_zeroes() --- backend/tests/test_composite.c | 48 ++++++++++++++++++++++++++++++++++ backend/tests/test_upcean.c | 13 +++++++-- backend/upcean.c | 6 +++-- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/backend/tests/test_composite.c b/backend/tests/test_composite.c index 790e545a..20a83576 100644 --- a/backend/tests/test_composite.c +++ b/backend/tests/test_composite.c @@ -1610,6 +1610,53 @@ static void test_encodation_11(void) testFinish(); } +// #181 Christian Hartlage OSS-Fuzz +static void test_fuzz(void) +{ + testStart(""); + + int ret; + struct item { + int symbology; + unsigned char* data; + int length; + unsigned char* composite; + int ret; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { BARCODE_EANX_CC, "+123456789012345678", -1, "[21]A12345678", ZINT_ERROR_TOO_LONG }, + /* 1*/ { BARCODE_UPCA_CC, "+123456789012345678", -1, "[21]A12345678", ZINT_ERROR_TOO_LONG }, + /* 2*/ { BARCODE_UPCE_CC, "+123456789012345678", -1, "[21]A12345678", ZINT_ERROR_TOO_LONG }, + /* 3*/ { BARCODE_EANX_CC, "+12345", -1, "[21]A12345678", 0 }, + /* 4*/ { BARCODE_EANX_CC, "+123456", -1, "[21]A12345678", ZINT_ERROR_TOO_LONG }, + }; + int data_size = sizeof(data) / sizeof(struct item); + + for (int i = 0; i < data_size; i++) { + + struct zint_symbol* symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + symbol->symbology = data[i].symbology; + int length = data[i].length; + if (length == -1) { + length = strlen(data[i].data); + } + assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length); + strcpy(symbol->primary, data[i].data); + + int composite_length = strlen(data[i].composite); + + ret = ZBarcode_Encode(symbol, data[i].composite, composite_length); + assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main() { test_eanx_leading_zeroes(); @@ -1620,6 +1667,7 @@ int main() test_encodation_0(); test_encodation_10(); test_encodation_11(); + test_fuzz(); testReport(); diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index 0999076f..f77a3d36 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -253,7 +253,7 @@ static void test_vector_same(void) } // #181 Christian Hartlage OSS-Fuzz -static void test_eanx_fuzz(void) +static void test_fuzz(void) { testStart(""); @@ -267,6 +267,15 @@ static void test_eanx_fuzz(void) // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) struct item data[] = { /* 0*/ { BARCODE_EANX, "55++15", -1, ZINT_ERROR_INVALID_DATA }, + /* 1*/ { BARCODE_EANX, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 2*/ { BARCODE_EANX_CHK, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 3*/ { BARCODE_UPCA, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 4*/ { BARCODE_UPCA_CHK, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 5*/ { BARCODE_UPCE, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 6*/ { BARCODE_UPCE_CHK, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 7*/ { BARCODE_ISBNX, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, + /* 8*/ { BARCODE_EANX, "+12345", -1, 0 }, + /* 9*/ { BARCODE_EANX, "+123456", -1, ZINT_ERROR_TOO_LONG }, }; int data_size = sizeof(data) / sizeof(struct item); @@ -296,7 +305,7 @@ int main() test_upca_print(); test_isbn(); test_vector_same(); - test_eanx_fuzz(); + test_fuzz(); testReport(); diff --git a/backend/upcean.c b/backend/upcean.c index 2c644f48..15fac07f 100644 --- a/backend/upcean.c +++ b/backend/upcean.c @@ -594,6 +594,9 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc first_part[i + 1] = '\0'; } + if (second_len >= 6) { /* Allow 6 (actual max 5) so as to trigger too long error */ + second_len = 6; + } for (i = 0; i < second_len; i++) { second_part[i] = source[i + first_len + 1]; second_part[i + 1] = '\0'; @@ -695,12 +698,11 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc /* splits string to parts before and after '+' parts */ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { - unsigned char first_part[20] = {0}, second_part[20] = {0}, dest[1000] = {0}; + unsigned char first_part[20] = {0}, second_part[7] = {0}, dest[1000] = {0}; unsigned char local_source[20] = {0}; unsigned int latch, reader, writer, with_addon; int error_number, i, plus_count; - with_addon = FALSE; latch = FALSE; writer = 0;