From defb4587de9db1bd1f25193685088ac23f3d8636 Mon Sep 17 00:00:00 2001 From: gitlost Date: Tue, 6 Sep 2022 15:58:53 +0100 Subject: [PATCH] telepen_num: strcpy -> memcpy to ensure temp buffer filled (#270) common: ensure stripf() not inlined to prevent optimizations undoing effect (#269), undo previous volatile temps workaround ([ac80b3]) --- backend/common.c | 17 ++++++------ backend/telepen.c | 16 +++++------ backend/tests/test_telepen.c | 54 +++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/backend/common.c b/backend/common.c index eac8fdb2..4fa00ac7 100644 --- a/backend/common.c +++ b/backend/common.c @@ -488,10 +488,7 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height, row_height = 0.5f; } if (min_row_height) { - /* This seems necessary to get gcc 12.2.1 to work consistently for static 32-bit builds */ - volatile const float row_height_strip = stripf(row_height); - volatile const float min_row_height_strip = stripf(min_row_height); - if (row_height_strip < min_row_height_strip) { + if (stripf(row_height) < stripf(min_row_height)) { error_number = ZINT_WARN_NONCOMPLIANT; if (!no_errtxt) { strcpy(symbol->errtxt, "247: Height not compliant with standards"); @@ -503,10 +500,7 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height, symbol->height = stripf(fixed_height); /* Ignore any given height */ } if (max_height) { - /* See above */ - volatile const float symbol_height_strip = stripf(symbol->height); - volatile const float max_height_strip = stripf(max_height); - if (symbol_height_strip > max_height_strip) { + if (stripf(symbol->height) > stripf(max_height)) { error_number = ZINT_WARN_NONCOMPLIANT; if (!no_errtxt) { strcpy(symbol->errtxt, "248: Height not compliant with standards"); @@ -517,6 +511,13 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height, return error_number; } +/* Prevent inlining of `stripf()` which can optimize away its effect */ +#if defined(__GNUC__) || defined(__clang__) +__attribute__((__noinline__)) +#endif +#if defined(_MSC_VER) && _MSC_VER >= 1310 /* MSVC 2003 (VC++ 7.1) */ +__declspec(noinline) +#endif /* Removes excess precision from floats - see https://stackoverflow.com/q/503436 */ INTERNAL float stripf(const float arg) { return *((volatile const float *) &arg); diff --git a/backend/telepen.c b/backend/telepen.c index c4fc87f1..e6a526bf 100644 --- a/backend/telepen.c +++ b/backend/telepen.c @@ -34,7 +34,7 @@ /* Telepen Barcode Symbology information and History (BSiH) https://telepen.co.uk/wp-content/uploads/2018/10/Barcode-Symbology-information-and-History.pdf */ -#define SODIUM_X_F (IS_NUM_F | IS_UX__F) /* SODIUM "0123456789X" */ +#define SODIUM_X_F (IS_NUM_F | IS_UX__F | IS_LX__F) /* SODIUM "0123456789Xx" */ #include #include "common.h" @@ -155,7 +155,7 @@ INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int int i; char dest[521]; /* 12 (start) + 30 * 16 (max for DELs) + 16 (check digit) + 12 (stop) + 1 = 521 */ char *d = dest; - unsigned char temp[64]; + unsigned char temp[61]; count = 0; @@ -163,20 +163,20 @@ INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int strcpy(symbol->errtxt, "392: Input too long (60 character maximum)"); return ZINT_ERROR_TOO_LONG; } - ustrcpy(temp, source); - to_upper(temp, src_len); - if (!is_sane(SODIUM_X_F, temp, src_len)) { + if (!is_sane(SODIUM_X_F, source, src_len)) { strcpy(symbol->errtxt, "393: Invalid character in data (digits and \"X\" only)"); return ZINT_ERROR_INVALID_DATA; } /* Add a leading zero if required */ if (src_len & 1) { - memmove(temp + 1, temp, src_len); + memcpy(temp + 1, source, src_len++); temp[0] = '0'; - - temp[++src_len] = '\0'; + } else { + memcpy(temp, source, src_len); } + temp[src_len] = '\0'; + to_upper(temp, src_len); /* Start character */ memcpy(d, TeleTable['_'], 12); diff --git a/backend/tests/test_telepen.c b/backend/tests/test_telepen.c index 64cb62e6..495b1ec6 100644 --- a/backend/tests/test_telepen.c +++ b/backend/tests/test_telepen.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* SPDX-License-Identifier: BSD-3-Clause */ #include "testcommon.h" @@ -40,7 +41,7 @@ static void test_large(int index, int debug) { int expected_rows; int expected_width; }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { /* 0*/ { BARCODE_TELEPEN, "\177", 30, 0, 1, 528 }, /* 1*/ { BARCODE_TELEPEN, "\177", 31, ZINT_ERROR_TOO_LONG, -1, -1 }, @@ -70,7 +71,7 @@ static void test_large(int index, int debug) { ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, 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 < 5) { + if (ret < ZINT_ERROR) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); } @@ -90,7 +91,7 @@ static void test_hrt(int index, int debug) { char *expected; }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { /* 0*/ { BARCODE_TELEPEN, "ABC1234.;$", -1, "ABC1234.;$" }, /* 1*/ { BARCODE_TELEPEN, "abc1234.;$", -1, "abc1234.;$" }, @@ -98,8 +99,8 @@ static void test_hrt(int index, int debug) { /* 3*/ { BARCODE_TELEPEN, "ABC\0001234", 8, "ABC 1234" }, /* 4*/ { BARCODE_TELEPEN_NUM, "1234", -1, "1234" }, /* 5*/ { BARCODE_TELEPEN_NUM, "123X", -1, "123X" }, - /* 6*/ { BARCODE_TELEPEN_NUM, "123x", -1, "123X" }, // Converts to upper - /* 7*/ { BARCODE_TELEPEN_NUM, "12345", -1, "012345" }, // Adds leading zero if odd + /* 6*/ { BARCODE_TELEPEN_NUM, "123x", -1, "123X" }, /* Converts to upper */ + /* 7*/ { BARCODE_TELEPEN_NUM, "12345", -1, "012345" }, /* Adds leading zero if odd */ }; int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -137,7 +138,7 @@ static void test_input(int index, int debug) { int expected_rows; int expected_width; }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { /* 0*/ { BARCODE_TELEPEN, " !\"#$%&'()*+,-./0123456789:;<", -1, 0, 1, 512 }, /* 1*/ { BARCODE_TELEPEN, "AZaz\176\001", -1, 0, 1, 144 }, @@ -145,9 +146,9 @@ static void test_input(int index, int debug) { /* 3*/ { BARCODE_TELEPEN, "é", -1, ZINT_ERROR_INVALID_DATA, -1, -1 }, /* 4*/ { BARCODE_TELEPEN_NUM, "1234567890", -1, 0, 1, 128 }, /* 5*/ { BARCODE_TELEPEN_NUM, "123456789A", -1, ZINT_ERROR_INVALID_DATA, -1, -1 }, - /* 6*/ { BARCODE_TELEPEN_NUM, "123456789X", -1, 0, 1, 128 }, // [0-9]X allowed - /* 7*/ { BARCODE_TELEPEN_NUM, "12345678X9", -1, ZINT_ERROR_INVALID_DATA, -1, -1 }, // X[0-9] not allowed - /* 8*/ { BARCODE_TELEPEN_NUM, "1X34567X9X", -1, 0, 1, 128 }, // [0-9]X allowed multiple times + /* 6*/ { BARCODE_TELEPEN_NUM, "123456789X", -1, 0, 1, 128 }, /* [0-9]X allowed */ + /* 7*/ { BARCODE_TELEPEN_NUM, "12345678X9", -1, ZINT_ERROR_INVALID_DATA, -1, -1 }, /* X[0-9] not allowed */ + /* 8*/ { BARCODE_TELEPEN_NUM, "1X34567X9X", -1, 0, 1, 128 }, /* [0-9]X allowed multiple times */ }; int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -167,7 +168,7 @@ static void test_input(int index, int 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); - if (ret < 5) { + if (ret < ZINT_ERROR) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); } @@ -178,8 +179,10 @@ static void test_input(int index, int debug) { testFinish(); } -// Telepen Barcode Symbology information and History (BSiH) https://telepen.co.uk/wp-content/uploads/2018/10/Barcode-Symbology-information-and-History.pdf -// E2326U: SB Telepen Barcode Fonts Guide Issue 2 (Apr 2009) https://telepen.co.uk/wp-content/uploads/2018/09/SB-Telepen-Barcode-Fonts-V2.pdf +/* Telepen Barcode Symbology information and History (BSiH) + https://telepen.co.uk/wp-content/uploads/2018/10/Barcode-Symbology-information-and-History.pdf */ +/* E2326U: SB Telepen Barcode Fonts Guide Issue 2 (Apr 2009) + https://telepen.co.uk/wp-content/uploads/2018/09/SB-Telepen-Barcode-Fonts-V2.pdf */ static void test_encode(int index, int generate, int debug) { struct item { @@ -233,7 +236,7 @@ static void test_encode(int index, int generate, int debug) { char bwipp_buf[8192]; char bwipp_msg[1024]; - int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ testStart("test_encode"); @@ -256,7 +259,7 @@ static void test_encode(int index, int generate, int debug) { testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); } else { - if (ret < 5) { + if (ret < ZINT_ERROR) { int width, row; assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); @@ -282,7 +285,7 @@ static void test_encode(int index, int generate, int debug) { testFinish(); } -// #181 Nico Gunkel OSS-Fuzz +/* #181 Nico Gunkel OSS-Fuzz */ static void test_fuzz(int index, int debug) { struct item { @@ -291,16 +294,17 @@ static void test_fuzz(int index, int debug) { int length; int ret; }; - // Note NULs where using DELs code (16 binary characters wide) - // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) + /* Note NULs where using DELs code (16 binary characters wide) */ + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_TELEPEN, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 30, 0 }, - /* 1*/ { BARCODE_TELEPEN, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 31, ZINT_ERROR_TOO_LONG }, - /* 2*/ { BARCODE_TELEPEN_NUM, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 60, ZINT_ERROR_INVALID_DATA }, - /* 3*/ { BARCODE_TELEPEN_NUM, "040404040404040404040404040404040404040404040404040404040404", 60, 0 }, - /* 4*/ { BARCODE_TELEPEN_NUM, "1234567890123456789012345678901234567890123456789012345678901", 61, ZINT_ERROR_TOO_LONG }, - /* 5*/ { BARCODE_TELEPEN_NUM, "00000000000000000000000000000000000000000000000000000000000X", 60, 0 }, - /* 6*/ { BARCODE_TELEPEN_NUM, "999999999999999999999999999999999999999999999999999999999999", 60, 0 }, + /* 0*/ { BARCODE_TELEPEN, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 30, 0 }, + /* 1*/ { BARCODE_TELEPEN, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 31, ZINT_ERROR_TOO_LONG }, + /* 2*/ { BARCODE_TELEPEN_NUM, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 60, ZINT_ERROR_INVALID_DATA }, + /* 3*/ { BARCODE_TELEPEN_NUM, "040404040404040404040404040404040404040404040404040404040404", 60, 0 }, + /* 4*/ { BARCODE_TELEPEN_NUM, "1234567890123456789012345678901234567890123456789012345678901", 61, ZINT_ERROR_TOO_LONG }, + /* 5*/ { BARCODE_TELEPEN_NUM, "00000000000000000000000000000000000000000000000000000000000X", 60, 0 }, + /* 6*/ { BARCODE_TELEPEN_NUM, "999999999999999999999999999999999999999999999999999999999999", 60, 0 }, + /* 7*/ { BARCODE_TELEPEN_NUM, "1234567890123456789012345678901234567890123456789012345678901234567890", 4, 0 }, /* Length given, strlen > 61, so pseudo not NUL-terminated */ }; int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -365,7 +369,7 @@ static const char TeleTable[128][16] = { {'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'}, }; -// Dummy to generate lengths table +/* Dummy to generate lengths table */ static void test_generate_lens(int generate) { int i;