From ebcd0a0d6d87b9b16c15fbcf6227303c7795cd86 Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 11 Feb 2021 13:51:07 +0000 Subject: [PATCH] #209 large.c fix oversized arrays by 0-filling; const args, casts --- backend/large.c | 28 ++++++++++++++-------------- backend/large.h | 20 ++++++++++---------- backend/tests/test_large.c | 19 +++++++++++-------- backend/tests/testcommon.c | 4 ++-- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/backend/large.c b/backend/large.c index 41203b33..9df5a1be 100644 --- a/backend/large.c +++ b/backend/large.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -55,7 +55,7 @@ #define MASK32 0xFFFFFFFF /* Convert decimal string `s` of (at most) length `length` to 64-bit and place in 128-bit `t` */ -INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length) { +INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, const int length) { uint64_t val = 0; const unsigned char *se = s + length; for (; s < se && *s >= '0' && *s <= '9'; s++) { @@ -73,7 +73,7 @@ INTERNAL void large_add(large_int *t, const large_int *s) { } /* Add 64-bit `s` to 128-bit `t` */ -INTERNAL void large_add_u64(large_int *t, uint64_t s) { +INTERNAL void large_add_u64(large_int *t, const uint64_t s) { t->lo += s; if (t->lo < s) { t->hi++; @@ -81,7 +81,7 @@ INTERNAL void large_add_u64(large_int *t, uint64_t s) { } /* Subtract 64-bit `s` from 128-bit `t` */ -INTERNAL void large_sub_u64(large_int *t, uint64_t s) { +INTERNAL void large_sub_u64(large_int *t, const uint64_t s) { uint64_t r = t->lo - s; if (r > t->lo) { t->hi--; @@ -110,7 +110,7 @@ INTERNAL void large_sub_u64(large_int *t, uint64_t s) { * p10 * p11 + k10 */ -INTERNAL void large_mul_u64(large_int *t, uint64_t s) { +INTERNAL void large_mul_u64(large_int *t, const uint64_t s) { uint64_t thi = t->hi; uint64_t tlo0 = t->lo & MASK32; uint64_t tlo1 = t->lo >> 32; @@ -237,7 +237,7 @@ INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v) { } /* Unset a bit (zero-based) */ -INTERNAL void large_unset_bit(large_int *t, int bit) { +INTERNAL void large_unset_bit(large_int *t, const int bit) { if (bit < 64) { t->lo &= ~(((uint64_t) 1) << bit); } else if (bit < 128) { @@ -246,7 +246,7 @@ INTERNAL void large_unset_bit(large_int *t, int bit) { } /* Output large_int into an unsigned int array of size `size`, each element containing `bits` bits */ -INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits) { +INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, const int size, int bits) { int i, j; uint64_t mask; if (bits <= 0) { @@ -270,37 +270,37 @@ INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int for (; i < size && j < 64; i++, j += bits) { uint_array[size - 1 - i] = (unsigned int) ((t->hi >> j) & mask); } - if (i < size && j != 128) { - uint_array[size - 1 - i] = (unsigned int) (t->hi >> (j - bits) & mask); + if (i < size) { + memset(uint_array, 0, sizeof(unsigned int) * (size - i)); } } } /* As `large_uint_array()` above, except output to unsigned char array */ -INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits) { +INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, const int size, int bits) { int i; #ifndef _MSC_VER unsigned int uint_array[size ? size : 1]; /* Avoid run-time warning if size is 0 */ #else - unsigned int *uint_array = (unsigned int *) _alloca((size ? size : 1) * sizeof(unsigned int)); + unsigned int *uint_array = (unsigned int *) _alloca(sizeof(unsigned int) * (size ? size : 1)); #endif large_uint_array(t, uint_array, size, bits); for (i = 0; i < size; i++) { - uchar_array[i] = uint_array[i]; + uchar_array[i] = (unsigned char) uint_array[i]; } } /* Output formatted large_int to stdout */ -INTERNAL void large_print(large_int *t) { +INTERNAL void large_print(const large_int *t) { char buf[35]; /* 2 (0x) + 32 (hex) + 1 */ puts(large_dump(t, buf)); } /* Format large_int into buffer, which should be at least 35 chars in size */ -INTERNAL char *large_dump(large_int *t, char *buf) { +INTERNAL char *large_dump(const large_int *t, char *buf) { unsigned int tlo1 = (unsigned int) (large_lo(t) >> 32); unsigned int tlo0 = (unsigned int) (large_lo(t) & MASK32); unsigned int thi1 = (unsigned int) (large_hi(t) >> 32); diff --git a/backend/large.h b/backend/large.h index 06325f5d..cd7f7f2c 100644 --- a/backend/large.h +++ b/backend/large.h @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -54,24 +54,24 @@ typedef struct { uint64_t lo; uint64_t hi; } large_int; /* Set 128-bit `t` from 64-bit `s` */ #define large_load_u64(t, s) do { (t)->lo = (s); (t)->hi = 0; } while (0) -INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length); +INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, const int length); INTERNAL void large_add(large_int *t, const large_int *s); -INTERNAL void large_add_u64(large_int *t, uint64_t s); +INTERNAL void large_add_u64(large_int *t, const uint64_t s); -INTERNAL void large_sub_u64(large_int *t, uint64_t s); +INTERNAL void large_sub_u64(large_int *t, const uint64_t s); -INTERNAL void large_mul_u64(large_int *t, uint64_t s); +INTERNAL void large_mul_u64(large_int *t, const uint64_t s); INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v); -INTERNAL void large_unset_bit(large_int *t, int bit); +INTERNAL void large_unset_bit(large_int *t, const int bit); -INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits); -INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits); +INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, const int size, int bits); +INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, const int size, int bits); -INTERNAL void large_print(large_int *t); -INTERNAL char *large_dump(large_int *t, char *buf); +INTERNAL void large_print(const large_int *t); +INTERNAL char *large_dump(const large_int *t, char *buf); #ifdef __cplusplus } diff --git a/backend/tests/test_large.c b/backend/tests/test_large.c index fcb016b5..eb7934b7 100644 --- a/backend/tests/test_large.c +++ b/backend/tests/test_large.c @@ -701,7 +701,7 @@ static void test_uint_array(int index) { large_int t; int size; int bits; - unsigned int expected[128]; + unsigned int expected[130]; }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { @@ -735,18 +735,21 @@ static void test_uint_array(int index) { /* 27*/ { LI(1, 1), 5, 31, { 0, 0, 4, 0, 1 } }, /* 28*/ { LI(1, 1), 4, 32, { 0, 1, 0, 1 } }, /* 29*/ { LI(1, 1), 4, 33, { 0, 1, 0, 1 } }, // Bits > 32 ignored and treated as 32 + /* 30*/ { LI(0xF0F0F0F0F0F0F0F0, 0xE0F0F0F0F0F0F0F0), 129, 1, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 } }, // Leading zeroes + /* 31*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 130, 1, { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, // Leading zeroes + /* 32*/ { LI(0xFFFFFFFFFFFFFFFF, 0xEFFFFFFFFFFFFFFF), 127, 1, { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, // Truncated }; int data_size = ARRAY_SIZE(data); char t_dump[35]; - char uint_dump[128 * 3]; - char uint_expected_dump[128 * 3]; - char uchar_dump[128 * 3]; - char uchar_expected_dump[128 * 3]; + char uint_dump[130 * 17 + 1]; + char uint_expected_dump[130 * 17 + 1]; + char uchar_dump[130 * 3 + 1]; + char uchar_expected_dump[130 * 3 + 1]; - unsigned int uint_array[128]; - unsigned char uchar_array[128]; - unsigned char uchar_expected_array[128]; + unsigned int uint_array[130]; + unsigned char uchar_array[130]; + unsigned char uchar_expected_array[130]; for (int i = 0; i < data_size; i++) { diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 7b67f872..1461f2d8 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -1052,7 +1052,7 @@ char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_ for (i = 0; i < size; i++) { cnt_len += sprintf(dump + cnt_len, "%X ", array[i]); - if (cnt_len + 19 > dump_size) { + if (cnt_len + 17 >= dump_size) { break; } } @@ -1065,7 +1065,7 @@ char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dum for (i = 0; i < size; i++) { cnt_len += sprintf(dump + cnt_len, "%X ", array[i]); - if (cnt_len + 3 > dump_size) { + if (cnt_len + 3 >= dump_size) { break; } }