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])
This commit is contained in:
gitlost 2022-09-06 15:58:53 +01:00
parent ac80b33c3c
commit defb4587de
3 changed files with 46 additions and 41 deletions

View file

@ -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);

View file

@ -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 <stdio.h>
#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);

View file

@ -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;