#209 large.c fix oversized arrays by 0-filling; const args, casts

This commit is contained in:
gitlost 2021-02-11 13:51:07 +00:00
parent 4875a3bcac
commit ebcd0a0d6d
4 changed files with 37 additions and 34 deletions

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -55,7 +55,7 @@
#define MASK32 0xFFFFFFFF #define MASK32 0xFFFFFFFF
/* Convert decimal string `s` of (at most) length `length` to 64-bit and place in 128-bit `t` */ /* 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; uint64_t val = 0;
const unsigned char *se = s + length; const unsigned char *se = s + length;
for (; s < se && *s >= '0' && *s <= '9'; s++) { 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` */ /* 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; t->lo += s;
if (t->lo < s) { if (t->lo < s) {
t->hi++; 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` */ /* 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; uint64_t r = t->lo - s;
if (r > t->lo) { if (r > t->lo) {
t->hi--; t->hi--;
@ -110,7 +110,7 @@ INTERNAL void large_sub_u64(large_int *t, uint64_t s) {
* p10 * p10
* p11 + k10 * 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 thi = t->hi;
uint64_t tlo0 = t->lo & MASK32; uint64_t tlo0 = t->lo & MASK32;
uint64_t tlo1 = t->lo >> 32; 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) */ /* 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) { if (bit < 64) {
t->lo &= ~(((uint64_t) 1) << bit); t->lo &= ~(((uint64_t) 1) << bit);
} else if (bit < 128) { } 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 */ /* 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; int i, j;
uint64_t mask; uint64_t mask;
if (bits <= 0) { 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) { for (; i < size && j < 64; i++, j += bits) {
uint_array[size - 1 - i] = (unsigned int) ((t->hi >> j) & mask); uint_array[size - 1 - i] = (unsigned int) ((t->hi >> j) & mask);
} }
if (i < size && j != 128) { if (i < size) {
uint_array[size - 1 - i] = (unsigned int) (t->hi >> (j - bits) & mask); memset(uint_array, 0, sizeof(unsigned int) * (size - i));
} }
} }
} }
/* As `large_uint_array()` above, except output to unsigned char array */ /* 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; int i;
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned int uint_array[size ? size : 1]; /* Avoid run-time warning if size is 0 */ unsigned int uint_array[size ? size : 1]; /* Avoid run-time warning if size is 0 */
#else #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 #endif
large_uint_array(t, uint_array, size, bits); large_uint_array(t, uint_array, size, bits);
for (i = 0; i < size; i++) { 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 */ /* 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 */ char buf[35]; /* 2 (0x) + 32 (hex) + 1 */
puts(large_dump(t, buf)); puts(large_dump(t, buf));
} }
/* Format large_int into buffer, which should be at least 35 chars in size */ /* 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 tlo1 = (unsigned int) (large_lo(t) >> 32);
unsigned int tlo0 = (unsigned int) (large_lo(t) & MASK32); unsigned int tlo0 = (unsigned int) (large_lo(t) & MASK32);
unsigned int thi1 = (unsigned int) (large_hi(t) >> 32); unsigned int thi1 = (unsigned int) (large_hi(t) >> 32);

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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` */ /* Set 128-bit `t` from 64-bit `s` */
#define large_load_u64(t, s) do { (t)->lo = (s); (t)->hi = 0; } while (0) #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(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 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_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, 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 void large_print(const large_int *t);
INTERNAL char *large_dump(large_int *t, char *buf); INTERNAL char *large_dump(const large_int *t, char *buf);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -701,7 +701,7 @@ static void test_uint_array(int index) {
large_int t; large_int t;
int size; int size;
int bits; int bits;
unsigned int expected[128]; unsigned int expected[130];
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { 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 } }, /* 27*/ { LI(1, 1), 5, 31, { 0, 0, 4, 0, 1 } },
/* 28*/ { LI(1, 1), 4, 32, { 0, 1, 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 /* 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); int data_size = ARRAY_SIZE(data);
char t_dump[35]; char t_dump[35];
char uint_dump[128 * 3]; char uint_dump[130 * 17 + 1];
char uint_expected_dump[128 * 3]; char uint_expected_dump[130 * 17 + 1];
char uchar_dump[128 * 3]; char uchar_dump[130 * 3 + 1];
char uchar_expected_dump[128 * 3]; char uchar_expected_dump[130 * 3 + 1];
unsigned int uint_array[128]; unsigned int uint_array[130];
unsigned char uchar_array[128]; unsigned char uchar_array[130];
unsigned char uchar_expected_array[128]; unsigned char uchar_expected_array[130];
for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) {

View File

@ -1052,7 +1052,7 @@ char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
cnt_len += sprintf(dump + cnt_len, "%X ", array[i]); cnt_len += sprintf(dump + cnt_len, "%X ", array[i]);
if (cnt_len + 19 > dump_size) { if (cnt_len + 17 >= dump_size) {
break; break;
} }
} }
@ -1065,7 +1065,7 @@ char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dum
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
cnt_len += sprintf(dump + cnt_len, "%X ", array[i]); cnt_len += sprintf(dump + cnt_len, "%X ", array[i]);
if (cnt_len + 3 > dump_size) { if (cnt_len + 3 >= dump_size) {
break; break;
} }
} }