From 7f8c8114f31c09a986597e0ba63a49f96150368a Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 25 Feb 2021 17:14:49 +0000 Subject: [PATCH] #218 Prevent buffer overflow in ean_leading_zeroes by checking max lengths --- backend/composite.c | 7 +- backend/tests/test_upcean.c | 210 +++++++++++++++++++----------------- backend/upcean.c | 28 ++--- 3 files changed, 135 insertions(+), 110 deletions(-) diff --git a/backend/composite.c b/backend/composite.c index 09240e6c..57882bd6 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -65,7 +65,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], +INTERNAL int ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], unsigned char local_source[], int *p_with_addon); INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); @@ -1322,7 +1322,10 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l int with_addon; unsigned char padded_pri[21]; padded_pri[0] = '\0'; - ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, padded_pri, &with_addon); + if (!ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, padded_pri, &with_addon)) { + strcpy(symbol->errtxt, "448: Input wrong length in linear component"); + return ZINT_ERROR_TOO_LONG; + } padded_pri_len = (int) ustrlen(padded_pri); if (padded_pri_len <= 7) { /* EAN-8 */ cc_width = 3; diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index b0a200c7..dc47c0ba 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -178,7 +178,7 @@ static void test_upca_input(int index, int debug) { /* 15*/ { BARCODE_UPCA, "123456789012+12345", 0 }, /* 16*/ { BARCODE_UPCA, "123456789017+12345", ZINT_ERROR_INVALID_CHECK }, /* 17*/ { BARCODE_UPCA, "123456789012+123456", ZINT_ERROR_TOO_LONG }, - /* 18*/ { BARCODE_UPCA, "123456789017+123456", ZINT_ERROR_INVALID_CHECK }, + /* 18*/ { BARCODE_UPCA, "123456789017+123456", ZINT_ERROR_TOO_LONG }, /* 19*/ { BARCODE_UPCA_CHK, "123456789012", 0 }, /* 20*/ { BARCODE_UPCA_CHK, "123456789011", ZINT_ERROR_INVALID_CHECK }, /* 21*/ { BARCODE_UPCA_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK }, @@ -268,101 +268,118 @@ static void test_eanx_input(int index, int debug) { /* 7*/ { BARCODE_EANX, "123456789012+12", 0 }, /* 8*/ { BARCODE_EANX, "1234567890128+12", 0 }, /* 9*/ { BARCODE_EANX, "1234567890122+12", ZINT_ERROR_INVALID_CHECK }, - /* 10*/ { BARCODE_EANX, "123456789012+123", 0 }, - /* 11*/ { BARCODE_EANX, "1234567890128+123", 0 }, - /* 12*/ { BARCODE_EANX, "1234567890123+123", ZINT_ERROR_INVALID_CHECK }, - /* 13*/ { BARCODE_EANX, "123456789012+1234", 0 }, - /* 14*/ { BARCODE_EANX, "1234567890128+1234", 0 }, - /* 15*/ { BARCODE_EANX, "1234567890124+1234", ZINT_ERROR_INVALID_CHECK }, - /* 16*/ { BARCODE_EANX, "123456789012+12345", 0 }, - /* 17*/ { BARCODE_EANX, "1234567890128+12345", 0 }, - /* 18*/ { BARCODE_EANX, "1234567890125+12345", ZINT_ERROR_INVALID_CHECK }, - /* 19*/ { BARCODE_EANX, "123456789012+123456", ZINT_ERROR_TOO_LONG }, - /* 20*/ { BARCODE_EANX, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, - /* 21*/ { BARCODE_EANX, "12345678901+123456", ZINT_ERROR_TOO_LONG }, - /* 22*/ { BARCODE_EANX, "12345678901+1234567", ZINT_ERROR_TOO_LONG }, - /* 23*/ { BARCODE_EANX, "1234567890+123456", ZINT_ERROR_TOO_LONG }, - /* 24*/ { BARCODE_EANX, "1234567890+1234567", ZINT_ERROR_TOO_LONG }, - /* 25*/ { BARCODE_EANX, "123456789+123456", ZINT_ERROR_TOO_LONG }, - /* 26*/ { BARCODE_EANX, "123456789+1234567", ZINT_ERROR_TOO_LONG }, - /* 27*/ { BARCODE_EANX, "12345678+123456", ZINT_ERROR_TOO_LONG }, - /* 28*/ { BARCODE_EANX, "1234567+123456", ZINT_ERROR_TOO_LONG }, // EAN-8 - /* 29*/ { BARCODE_EANX, "123456+123456", ZINT_ERROR_TOO_LONG }, - /* 30*/ { BARCODE_EANX, "12345+123456", ZINT_ERROR_TOO_LONG }, - /* 31*/ { BARCODE_EANX, "1234+123456", ZINT_ERROR_TOO_LONG }, - /* 32*/ { BARCODE_EANX, "123+123456", ZINT_ERROR_TOO_LONG }, - /* 33*/ { BARCODE_EANX, "12+123456", ZINT_ERROR_TOO_LONG }, - /* 34*/ { BARCODE_EANX, "1+123456", ZINT_ERROR_TOO_LONG }, - /* 35*/ { BARCODE_EANX, "1+12345678901234", ZINT_ERROR_TOO_LONG }, - /* 36*/ { BARCODE_EANX, "1+12345", 0 }, - /* 37*/ { BARCODE_EANX, "1+", 0 }, // EAN-2 - /* 38*/ { BARCODE_EANX, "+1", 0 }, // EAN-8 - /* 39*/ { BARCODE_EANX, "+", 0 }, // EAN-2 - /* 40*/ { BARCODE_EANX, "1", 0 }, // EAN-2 - /* 41*/ { BARCODE_EANX, "12", 0 }, // EAN-2 - /* 42*/ { BARCODE_EANX, "123", 0 }, // EAN-5 - /* 43*/ { BARCODE_EANX, "1234567890123456789", ZINT_ERROR_TOO_LONG }, - /* 44*/ { BARCODE_EANX_CHK, "123456789012", 0 }, // EANX_CHK accepts no CHK - /* 45*/ { BARCODE_EANX_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK }, // But only if no leading zeroes required - /* 46*/ { BARCODE_EANX_CHK, "12345678905", 0 }, - /* 47*/ { BARCODE_EANX_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK }, - /* 48*/ { BARCODE_EANX_CHK, "123456789", ZINT_ERROR_INVALID_CHECK }, - /* 49*/ { BARCODE_EANX_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, // EAN-8 - /* 50*/ { BARCODE_EANX_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, - /* 51*/ { BARCODE_EANX_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, - /* 52*/ { BARCODE_EANX_CHK, "12345", 0 }, // EAN-5 - /* 53*/ { BARCODE_EANX_CHK, "1234", 0 }, - /* 54*/ { BARCODE_EANX_CHK, "123", 0 }, - /* 55*/ { BARCODE_EANX_CHK, "12", 0 }, // EAN-2 - /* 56*/ { BARCODE_EANX_CHK, "1", 0 }, - /* 57*/ { BARCODE_EANX_CHK, "1234567890128", 0 }, - /* 58*/ { BARCODE_EANX_CHK, "1234567890126", ZINT_ERROR_INVALID_CHECK }, - /* 59*/ { BARCODE_EANX_CHK, "123456789012+1", 0 }, - /* 60*/ { BARCODE_EANX_CHK, "1234567890128+1", 0 }, - /* 61*/ { BARCODE_EANX_CHK, "1234567890127+1", ZINT_ERROR_INVALID_CHECK }, - /* 62*/ { BARCODE_EANX_CHK, "123456789012+12", 0 }, - /* 63*/ { BARCODE_EANX_CHK, "1234567890128+12", 0 }, - /* 64*/ { BARCODE_EANX_CHK, "1234567890129+12", ZINT_ERROR_INVALID_CHECK }, - /* 65*/ { BARCODE_EANX_CHK, "123456789012+123", 0 }, - /* 66*/ { BARCODE_EANX_CHK, "1234567890128+123", 0 }, - /* 67*/ { BARCODE_EANX_CHK, "1234567890120+1234", ZINT_ERROR_INVALID_CHECK }, - /* 68*/ { BARCODE_EANX_CHK, "123456789012+1234", 0 }, - /* 69*/ { BARCODE_EANX_CHK, "1234567890128+1234", 0 }, - /* 70*/ { BARCODE_EANX_CHK, "1234567890121+1234", ZINT_ERROR_INVALID_CHECK }, - /* 71*/ { BARCODE_EANX_CHK, "123456789012+12345", 0 }, - /* 72*/ { BARCODE_EANX_CHK, "1234567890128+12345", 0 }, - /* 73*/ { BARCODE_EANX_CHK, "1234567890122+12345", ZINT_ERROR_INVALID_CHECK }, - /* 74*/ { BARCODE_EANX_CHK, "123456789012+123456", ZINT_ERROR_TOO_LONG }, - /* 75*/ { BARCODE_EANX_CHK, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, - /* 76*/ { BARCODE_EANX_CHK, "12345678901+123456", ZINT_ERROR_INVALID_CHECK }, // Note different behaviour than EANX due to leading zeroes added - /* 77*/ { BARCODE_EANX_CHK, "12345678901+1234567", ZINT_ERROR_INVALID_CHECK }, - /* 78*/ { BARCODE_EANX_CHK, "12345678901+12345", ZINT_ERROR_INVALID_CHECK }, - /* 79*/ { BARCODE_EANX_CHK, "1234567890+12345", ZINT_ERROR_INVALID_CHECK }, - /* 80*/ { BARCODE_EANX_CHK, "1234567890+123456", ZINT_ERROR_INVALID_CHECK }, - /* 81*/ { BARCODE_EANX_CHK, "123456789+12345", ZINT_ERROR_INVALID_CHECK }, - /* 82*/ { BARCODE_EANX_CHK, "12345678+12345", ZINT_ERROR_INVALID_CHECK }, // EAN-8 - /* 83*/ { BARCODE_EANX_CHK, "12345670+12345", 0 }, - /* 84*/ { BARCODE_EANX_CHK, "1234567+12345", ZINT_ERROR_INVALID_CHECK }, - /* 85*/ { BARCODE_EANX_CHK, "1234565+12345", 0 }, - /* 86*/ { BARCODE_EANX_CHK, "123456+12345", ZINT_ERROR_INVALID_CHECK }, - /* 87*/ { BARCODE_EANX_CHK, "123457+12345", 0 }, - /* 88*/ { BARCODE_EANX_CHK, "12345+12345", ZINT_ERROR_INVALID_CHECK }, - /* 89*/ { BARCODE_EANX_CHK, "12348+12345", 0 }, - /* 90*/ { BARCODE_EANX_CHK, "1234+12345", ZINT_ERROR_INVALID_CHECK }, - /* 91*/ { BARCODE_EANX_CHK, "1236+12345", 0 }, - /* 92*/ { BARCODE_EANX_CHK, "123+12345", 0 }, // 3 happens to be correct check digit - /* 93*/ { BARCODE_EANX_CHK, "124+12345", ZINT_ERROR_INVALID_CHECK }, - /* 94*/ { BARCODE_EANX_CHK, "12+12345", ZINT_ERROR_INVALID_CHECK }, - /* 95*/ { BARCODE_EANX_CHK, "17+12345", 0 }, - /* 96*/ { BARCODE_EANX_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK }, - /* 97*/ { BARCODE_EANX_CHK, "0+12345", 0 }, - /* 98*/ { BARCODE_EANX_CHK, "0+123456", ZINT_ERROR_TOO_LONG }, - /* 99*/ { BARCODE_EANX_CHK, "1+12345678901234", ZINT_ERROR_INVALID_CHECK }, - /*100*/ { BARCODE_EANX_CHK, "0+12345678901234", ZINT_ERROR_TOO_LONG }, - /*101*/ { BARCODE_EANX_CHK, "1+", 0 }, // EAN-2 - /*102*/ { BARCODE_EANX_CHK, "+1", 0 }, // EAN-8 - /*103*/ { BARCODE_EANX_CHK, "+", 0 }, // EAN-2 - /*104*/ { BARCODE_EANX_CHK, "1234567890123456789", ZINT_ERROR_TOO_LONG }, + /* 10*/ { BARCODE_EANX, "12345678901234+12", ZINT_ERROR_TOO_LONG }, + /* 11*/ { BARCODE_EANX, "123456789012345+12", ZINT_ERROR_TOO_LONG }, + /* 12*/ { BARCODE_EANX, "1234567890123456+12", ZINT_ERROR_TOO_LONG }, + /* 13*/ { BARCODE_EANX, "123456789012+123", 0 }, + /* 14*/ { BARCODE_EANX, "1234567890128+123", 0 }, + /* 15*/ { BARCODE_EANX, "1234567890123+123", ZINT_ERROR_INVALID_CHECK }, + /* 16*/ { BARCODE_EANX, "12345678901234+123", ZINT_ERROR_TOO_LONG }, + /* 17*/ { BARCODE_EANX, "123456789012345+123", ZINT_ERROR_TOO_LONG }, + /* 18*/ { BARCODE_EANX, "123456789012+1234", 0 }, + /* 19*/ { BARCODE_EANX, "1234567890128+1234", 0 }, + /* 20*/ { BARCODE_EANX, "1234567890124+1234", ZINT_ERROR_INVALID_CHECK }, + /* 21*/ { BARCODE_EANX, "12345678901234+1234", ZINT_ERROR_TOO_LONG }, + /* 22*/ { BARCODE_EANX, "123456789012+12345", 0 }, + /* 23*/ { BARCODE_EANX, "1234567890128+12345", 0 }, + /* 24*/ { BARCODE_EANX, "12345678901234+12345", ZINT_ERROR_TOO_LONG }, + /* 25*/ { BARCODE_EANX, "1234567890125+12345", ZINT_ERROR_INVALID_CHECK }, + /* 26*/ { BARCODE_EANX, "123456789012+123456", ZINT_ERROR_TOO_LONG }, + /* 27*/ { BARCODE_EANX, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, + /* 28*/ { BARCODE_EANX, "12345678901+123456", ZINT_ERROR_TOO_LONG }, + /* 29*/ { BARCODE_EANX, "12345678901+1234567", ZINT_ERROR_TOO_LONG }, + /* 30*/ { BARCODE_EANX, "1234567890+123456", ZINT_ERROR_TOO_LONG }, + /* 31*/ { BARCODE_EANX, "1234567890+1234567", ZINT_ERROR_TOO_LONG }, + /* 32*/ { BARCODE_EANX, "123456789+123456", ZINT_ERROR_TOO_LONG }, + /* 33*/ { BARCODE_EANX, "123456789+1234567", ZINT_ERROR_TOO_LONG }, + /* 34*/ { BARCODE_EANX, "12345678+123456", ZINT_ERROR_TOO_LONG }, + /* 35*/ { BARCODE_EANX, "1234567+123456", ZINT_ERROR_TOO_LONG }, // EAN-8 + /* 36*/ { BARCODE_EANX, "123456+123456", ZINT_ERROR_TOO_LONG }, + /* 37*/ { BARCODE_EANX, "12345+123456", ZINT_ERROR_TOO_LONG }, + /* 38*/ { BARCODE_EANX, "1234+123456", ZINT_ERROR_TOO_LONG }, + /* 39*/ { BARCODE_EANX, "123+123456", ZINT_ERROR_TOO_LONG }, + /* 40*/ { BARCODE_EANX, "12+123456", ZINT_ERROR_TOO_LONG }, + /* 41*/ { BARCODE_EANX, "1+123456", ZINT_ERROR_TOO_LONG }, + /* 42*/ { BARCODE_EANX, "1+12345678901234", ZINT_ERROR_TOO_LONG }, + /* 43*/ { BARCODE_EANX, "1+12345", 0 }, + /* 44*/ { BARCODE_EANX, "1+", 0 }, // EAN-2 + /* 45*/ { BARCODE_EANX, "+1", 0 }, // EAN-8 + /* 46*/ { BARCODE_EANX, "+", 0 }, // EAN-2 + /* 47*/ { BARCODE_EANX, "1", 0 }, // EAN-2 + /* 48*/ { BARCODE_EANX, "12", 0 }, // EAN-2 + /* 49*/ { BARCODE_EANX, "123", 0 }, // EAN-5 + /* 50*/ { BARCODE_EANX, "12345678901234", ZINT_ERROR_TOO_LONG }, + /* 51*/ { BARCODE_EANX, "123456789012345", ZINT_ERROR_TOO_LONG }, + /* 52*/ { BARCODE_EANX, "1234567890123456", ZINT_ERROR_TOO_LONG }, + /* 53*/ { BARCODE_EANX, "12345678901234567", ZINT_ERROR_TOO_LONG }, + /* 54*/ { BARCODE_EANX, "123456789012345678", ZINT_ERROR_TOO_LONG }, + /* 55*/ { BARCODE_EANX, "1234567890123456789", ZINT_ERROR_TOO_LONG }, + /* 56*/ { BARCODE_EANX_CHK, "123456789012", 0 }, // EANX_CHK accepts no CHK + /* 57*/ { BARCODE_EANX_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK }, // But only if no leading zeroes required + /* 58*/ { BARCODE_EANX_CHK, "12345678905", 0 }, + /* 59*/ { BARCODE_EANX_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK }, + /* 60*/ { BARCODE_EANX_CHK, "123456789", ZINT_ERROR_INVALID_CHECK }, + /* 61*/ { BARCODE_EANX_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, // EAN-8 + /* 62*/ { BARCODE_EANX_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, + /* 63*/ { BARCODE_EANX_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, + /* 64*/ { BARCODE_EANX_CHK, "12345", 0 }, // EAN-5 + /* 65*/ { BARCODE_EANX_CHK, "1234", 0 }, + /* 66*/ { BARCODE_EANX_CHK, "123", 0 }, + /* 67*/ { BARCODE_EANX_CHK, "12", 0 }, // EAN-2 + /* 68*/ { BARCODE_EANX_CHK, "1", 0 }, + /* 69*/ { BARCODE_EANX_CHK, "1234567890128", 0 }, + /* 70*/ { BARCODE_EANX_CHK, "1234567890126", ZINT_ERROR_INVALID_CHECK }, + /* 71*/ { BARCODE_EANX_CHK, "123456789012+1", 0 }, + /* 72*/ { BARCODE_EANX_CHK, "1234567890128+1", 0 }, + /* 73*/ { BARCODE_EANX_CHK, "1234567890127+1", ZINT_ERROR_INVALID_CHECK }, + /* 74*/ { BARCODE_EANX_CHK, "123456789012+12", 0 }, + /* 75*/ { BARCODE_EANX_CHK, "1234567890128+12", 0 }, + /* 76*/ { BARCODE_EANX_CHK, "1234567890129+12", ZINT_ERROR_INVALID_CHECK }, + /* 77*/ { BARCODE_EANX_CHK, "123456789012+123", 0 }, + /* 78*/ { BARCODE_EANX_CHK, "1234567890128+123", 0 }, + /* 79*/ { BARCODE_EANX_CHK, "1234567890120+1234", ZINT_ERROR_INVALID_CHECK }, + /* 80*/ { BARCODE_EANX_CHK, "123456789012+1234", 0 }, + /* 81*/ { BARCODE_EANX_CHK, "1234567890128+1234", 0 }, + /* 82*/ { BARCODE_EANX_CHK, "1234567890121+1234", ZINT_ERROR_INVALID_CHECK }, + /* 83*/ { BARCODE_EANX_CHK, "123456789012+12345", 0 }, + /* 84*/ { BARCODE_EANX_CHK, "1234567890128+12345", 0 }, + /* 85*/ { BARCODE_EANX_CHK, "1234567890122+12345", ZINT_ERROR_INVALID_CHECK }, + /* 86*/ { BARCODE_EANX_CHK, "123456789012+123456", ZINT_ERROR_TOO_LONG }, + /* 87*/ { BARCODE_EANX_CHK, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, + /* 88*/ { BARCODE_EANX_CHK, "12345678901+123456", ZINT_ERROR_TOO_LONG }, + /* 89*/ { BARCODE_EANX_CHK, "12345678901+1234567", ZINT_ERROR_TOO_LONG }, + /* 90*/ { BARCODE_EANX_CHK, "12345678901+12345", ZINT_ERROR_INVALID_CHECK }, + /* 91*/ { BARCODE_EANX_CHK, "1234567890+12345", ZINT_ERROR_INVALID_CHECK }, + /* 92*/ { BARCODE_EANX_CHK, "1234567890+123456", ZINT_ERROR_TOO_LONG }, + /* 93*/ { BARCODE_EANX_CHK, "123456789+12345", ZINT_ERROR_INVALID_CHECK }, + /* 94*/ { BARCODE_EANX_CHK, "12345678+12345", ZINT_ERROR_INVALID_CHECK }, // EAN-8 + /* 95*/ { BARCODE_EANX_CHK, "12345670+12345", 0 }, + /* 96*/ { BARCODE_EANX_CHK, "1234567+12345", ZINT_ERROR_INVALID_CHECK }, + /* 97*/ { BARCODE_EANX_CHK, "1234565+12345", 0 }, + /* 98*/ { BARCODE_EANX_CHK, "123456+12345", ZINT_ERROR_INVALID_CHECK }, + /* 99*/ { BARCODE_EANX_CHK, "123457+12345", 0 }, + /*100*/ { BARCODE_EANX_CHK, "12345+12345", ZINT_ERROR_INVALID_CHECK }, + /*101*/ { BARCODE_EANX_CHK, "12348+12345", 0 }, + /*102*/ { BARCODE_EANX_CHK, "1234+12345", ZINT_ERROR_INVALID_CHECK }, + /*103*/ { BARCODE_EANX_CHK, "1236+12345", 0 }, + /*104*/ { BARCODE_EANX_CHK, "123+12345", 0 }, // 3 happens to be correct check digit + /*105*/ { BARCODE_EANX_CHK, "124+12345", ZINT_ERROR_INVALID_CHECK }, + /*106*/ { BARCODE_EANX_CHK, "12+12345", ZINT_ERROR_INVALID_CHECK }, + /*107*/ { BARCODE_EANX_CHK, "17+12345", 0 }, + /*108*/ { BARCODE_EANX_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK }, + /*109*/ { BARCODE_EANX_CHK, "0+12345", 0 }, + /*110*/ { BARCODE_EANX_CHK, "0+123456", ZINT_ERROR_TOO_LONG }, + /*111*/ { BARCODE_EANX_CHK, "1+12345678901234", ZINT_ERROR_TOO_LONG }, + /*112*/ { BARCODE_EANX_CHK, "0+12345678901234", ZINT_ERROR_TOO_LONG }, + /*113*/ { BARCODE_EANX_CHK, "1+", 0 }, // EAN-2 + /*114*/ { BARCODE_EANX_CHK, "+1", 0 }, // EAN-8 + /*115*/ { BARCODE_EANX_CHK, "+", 0 }, // EAN-2 + /*116*/ { BARCODE_EANX_CHK, "12345678901234", ZINT_ERROR_TOO_LONG }, + /*117*/ { BARCODE_EANX_CHK, "123456789012345", ZINT_ERROR_TOO_LONG }, + /*118*/ { BARCODE_EANX_CHK, "1234567890123456", ZINT_ERROR_TOO_LONG }, + /*119*/ { BARCODE_EANX_CHK, "12345678901234567", ZINT_ERROR_TOO_LONG }, + /*120*/ { BARCODE_EANX_CHK, "123456789012345678", ZINT_ERROR_TOO_LONG }, + /*121*/ { BARCODE_EANX_CHK, "1234567890123456789", ZINT_ERROR_TOO_LONG }, }; int data_size = ARRAY_SIZE(data); @@ -738,6 +755,7 @@ static void test_fuzz(int index, int debug) { /* 7*/ { BARCODE_ISBNX, "+123456789012345678", -1, ZINT_ERROR_TOO_LONG }, /* 8*/ { BARCODE_EANX, "+12345", -1, 0 }, /* 9*/ { BARCODE_EANX, "+123456", -1, ZINT_ERROR_TOO_LONG }, + /*10*/ { BARCODE_EANX, "000002000000200+203", -1, ZINT_ERROR_TOO_LONG }, // #218 Jan Schrewe CI-Fuzz }; int data_size = ARRAY_SIZE(data); diff --git a/backend/upcean.c b/backend/upcean.c index 1692bc57..be3cb67d 100644 --- a/backend/upcean.c +++ b/backend/upcean.c @@ -120,7 +120,7 @@ static void upca_draw(const char source[], const int length, unsigned char dest[ /* Make a UPC A barcode when we haven't been given the check digit */ static int upca(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char dest[]) { - char gtin[15]; + char gtin[13]; int error_number = 0; ustrcpy(gtin, source); @@ -370,7 +370,7 @@ static char ean_check(const char source[], const int length) { static int ean13(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char dest[]) { int i, half_way; char parity[6]; - char gtin[15]; + char gtin[14]; int error_number = 0; parity[0] = '\0'; @@ -543,9 +543,9 @@ static int isbn(struct zint_symbol *symbol, unsigned char source[], const int sr } /* Add leading zeroes to EAN and UPC strings */ -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], +INTERNAL int ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], unsigned char local_source[], int *p_with_addon) { - unsigned char first_part[20], second_part[7], zfirst_part[20], zsecond_part[7]; + unsigned char first_part[14], second_part[6], zfirst_part[14], zsecond_part[6]; int with_addon = 0; int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; @@ -561,6 +561,9 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char } } } + if (first_len > 13 || second_len > 5) { + return 0; + } /* Split input into two strings */ for (i = 0; i < first_len; i++) { @@ -568,9 +571,6 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char } first_part[first_len] = '\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]; } @@ -679,12 +679,13 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char if (p_with_addon) { *p_with_addon = with_addon; } + + return 1; /* Success */ } -/* 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[7] = {0}, dest[1000] = {0}; - unsigned char local_source[21] = {0}; /* Allow 13 + "+" + 6 (too long add-on) + 1 */ + unsigned char first_part[14] = {0}, second_part[6] = {0}, dest[1000] = {0}; + unsigned char local_source[20] = {0}; /* Allow 13 + "+" + 5 + 1 */ int latch, reader, writer; int with_addon; int error_number, i, plus_count; @@ -725,8 +726,11 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le return ZINT_ERROR_INVALID_DATA; } - /* Add leading zeroes */ - ean_leading_zeroes(symbol, source, local_source, &with_addon); + /* Add leading zeroes, checking max lengths of parts */ + if (!ean_leading_zeroes(symbol, source, local_source, &with_addon)) { + strcpy(symbol->errtxt, "294: Input too long"); + return ZINT_ERROR_TOO_LONG; + } reader = 0; if (with_addon) {