AZTEC: fix another out-of-bounds crash when user-specified size given

ticket #300 (no. 3), props Andre Maute
This commit is contained in:
gitlost 2023-11-24 10:30:57 +00:00
parent 7c4a538248
commit 86748999a4
2 changed files with 129 additions and 49 deletions

View File

@ -839,8 +839,43 @@ static void az_populate_map(short AztecMap[], const int layers) {
} }
} }
/* Helper to insert dummy '0' or '1's into runs of same bits. See ISO/IEC 24778:2008 7.3.1.2 */
static int az_bitrun_stuff(const char *binary_string, const int data_length, const int codeword_size,
char adjusted_string[AZTEC_MAX_CAPACITY]) {
int i, j = 0, count = 0;
for (i = 0; i < data_length; i++) {
if ((j + 1) % codeword_size == 0) {
/* Last bit of codeword */
/* 7.3.1.2 "whenever the first B-1 bits ... are all “0”s, then a dummy “1” is inserted..."
"Similarly a message codeword that starts with B-1 “1”s has a dummy “0” inserted..." */
if (count == 0 || count == (codeword_size - 1)) {
/* Codeword of B-1 '0's or B-1 '1's */
if (j >= AZTEC_MAX_CAPACITY) {
return 0; /* Fail */
}
adjusted_string[j++] = count == 0 ? '1' : '0';
count = binary_string[i] == '1' ? 1 : 0;
} else {
count = 0;
}
} else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
count++;
}
if (j >= AZTEC_MAX_CAPACITY) {
return 0; /* Fail */
}
adjusted_string[j++] = binary_string[i];
}
return j;
}
INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int x, y, i, j, p, data_blocks, ecc_blocks, layers, total_bits; int x, y, i, p, data_blocks, ecc_blocks, layers, total_bits;
char bit_pattern[AZTEC_MAP_POSN_MAX + 1]; /* Note AZTEC_MAP_POSN_MAX > AZTEC_BIN_CAPACITY */ char bit_pattern[AZTEC_MAP_POSN_MAX + 1]; /* Note AZTEC_MAP_POSN_MAX > AZTEC_BIN_CAPACITY */
/* To lessen stack usage, share binary_string buffer with bit_pattern, as accessed separately */ /* To lessen stack usage, share binary_string buffer with bit_pattern, as accessed separately */
char *binary_string = bit_pattern; char *binary_string = bit_pattern;
@ -1024,31 +1059,11 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
codeword_size = 12; codeword_size = 12;
} }
j = 0; adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size, adjusted_string);
count = 0; if (adjusted_length == 0) {
for (i = 0; i < data_length; i++) { strcpy(symbol->errtxt, "705: Data too long for specified Aztec Code symbol size");
if ((j + 1) % codeword_size == 0) { return ZINT_ERROR_TOO_LONG;
/* Last bit of codeword */
/* 7.3.1.2 "whenever the first B-1 bits ... are all “0”s, then a dummy “1” is inserted..."
"Similarly a message codeword that starts with B-1 “1”s has a dummy “0” inserted..." */
if (count == 0 || count == (codeword_size - 1)) {
/* Codeword of B-1 '0's or B-1 '1's */
adjusted_string[j] = count == 0 ? '1' : '0';
j++;
count = binary_string[i] == '1' ? 1 : 0;
} else {
count = 0;
}
} else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
count++;
}
adjusted_string[j] = binary_string[i];
j++;
} }
adjusted_length = j;
adjustment_size = adjusted_length - data_length; adjustment_size = adjusted_length - data_length;
/* Add padding */ /* Add padding */
@ -1107,31 +1122,11 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
codeword_size = 12; codeword_size = 12;
} }
j = 0; adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size, adjusted_string);
count = 0; if (adjusted_length == 0) {
for (i = 0; i < data_length; i++) { strcpy(symbol->errtxt, "704: Data too long for specified Aztec Code symbol size");
return ZINT_ERROR_TOO_LONG;
if ((j + 1) % codeword_size == 0) {
/* Last bit of codeword */
if (count == 0 || count == (codeword_size - 1)) {
/* Codeword of B-1 '0's or B-1 '1's */
if (j + 1 >= AZTEC_MAX_CAPACITY) {
strcpy(symbol->errtxt, "704: Data too long for specified Aztec Code symbol size");
return ZINT_ERROR_TOO_LONG;
}
adjusted_string[j++] = count == 0 ? '1' : '0';
count = binary_string[i] == '1' ? 1 : 0;
} else {
count = 0;
}
} else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
count++;
}
adjusted_string[j++] = binary_string[i];
} }
adjusted_length = j;
remainder = adjusted_length % codeword_size; remainder = adjusted_length % codeword_size;

View File

@ -3481,6 +3481,91 @@ static void test_fuzz(const testCtx *const p_ctx) {
"111", "111",
2054, DATA_MODE, 1, -1, 0 2054, DATA_MODE, 1, -1, 0
}, /* 2048 byte block surrounded by digits */ }, /* 2048 byte block surrounded by digits */
/* 10*/ { BARCODE_AZTEC,
"\105\105\000\000\000\000\000\000\000\000\077\012\377\377\377\072\376\376\350\350\350\350\350\250\350\350\350\350\354\350\350\350\350\350\001\000\000\000\000\000"
"\000\036\103\012\072\103\103\000\100\116\000\000\000\000\000\000\000\000\000\000\002\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\077\012"
"\377\377\377\072\376\376\350\350\350\350\350\250\350\350\350\350\354\350\350\350\000\000\000\000\000\000\000\033\000\036\103\012\072\103\103\000\100\116\000\000"
"\000\000\000\000\000\000\000\000\000\222\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\012\000\000\000\000\072\103\103\103\103\012\012\000\365\365\365\365\365\365\374\365\365\365\365\365\000\000\001\000\000\000\000\000\100\377\337\377"
"\377\377\377\377\000\000\000\000\372\377\000\100\377\377\350\350\000\000\350\350\350\350\350\350\350\350\001\000\000\000\000\000\000\036\103\012\072\103\365\000"
"\000\000\000\000\000\000\000\000\377\377\377\350\350\350\350\350\350\350\350\350\350\350\350\350\350\061\350\350\350\350\354\350\350\350\350\350\001\000\000\000"
"\000\000\000\036\103\012\072\103\103\000\100\116\000\000\000\000\000\000\000\000\000\000\000\216\000\000\000\000\000\000\000\377\377\377\377\377\377\377\000\000"
"\377\365\374\365\365\365\365\001\236\365\000\000\001\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\064\064\064\064\064\064\064\064\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153"
"\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\064\064\064\064\064\064\064\064\064\064\044\064\064\064\064\064\064\064\064\064"
"\064\064\064\064\064\064\064\064\064\064\064\064\064\064\064\064\064\264\264\362\362\362\362\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242"
"\242\242\242\242\242\242\242\242\242\242\242\242\242\103\000\100\116\000\000\000\000\000\000\000\000\000\000\000\222\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\012\000\000\000\000\072\103\103\103\103\012\012\000\365\365\365\365\365"
"\365\374\365\365\365\365\365\000\000\001\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\001"
"\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\100\377\377\377\377\377\377\377\000\000\000\000"
"\000\000\000\100\377\377\350\350\000\000\350\350\350\350\350\350\350\350\001\000\000\000\000\000\000\036\103\012\072\103\365\000\000\000\000\000\000\000\266\266"
"\266\266\112\000\000\000\266\266\266\266\266\266\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\022\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\077\012\377"
"\377\377\072\376\376\350\350\350\350\350\000\000\000\000\001\000\000\000\350\350\350\001\000\000\000\000\000\000\036\103\012\072\103\103\000\100\116\000\000\000"
"\000\000\000\000\000\000\000\000\222\000\000\000\000\000\000\000\000\000\000\025\000\000\000\000\001\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000"
"\000\000\012\000\000\000\000\072\103\103\103\103\012\012\000\365\365\365\365\365\365\374\365\365\365\365\365\000\000\000\311\000\000\000\000\100\377\337\377\377"
"\377\377\377\000\000\000\000\000\000\000\100\377\377\350\353\000\000\350\150\350\350\350\350\350\350\001\000\000\000\000\000\000\036\103\012\072\103\365\000\000"
"\000\000\000\000\000\047\000\377\377\377\350\350\350\350\350\350\350\350\350\350\350\350\350\350\254\350\350\350\350\354\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\350\350\350\350\350\001\000\000\127\000\000\000\036\103"
"\012\072\103\103\000\100\116\000\000\000\000\000\000\000\000\000\000\000\220\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\050\050\050\000\000\000"
"\000\000\000\000\000\000\001\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"
"\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000\000\000\000\000\266"
"\266\266\266\266\266\377\377\377\377\377\013\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\005\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\172\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\266\266\266\266\266\266\266\266\266\266\377\377\377\377\377\377\377\377\377\377\377\377\044"
"\377\377\377\377\377\377\050\064\064\064\000\000\000\000\072\376\376\350\350\350\350\350\350\377\377\377\377\377\377\377\377\377\377\377\377\377\005\377\377\377"
"\377\350\350\350\350\350\350\350\310\350\350\001\000\000\000\000\000\000\036\103\012\072\103\103\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\310\000\064\064\064\064\064\064\064\064\064\064\064\064\064\064\073\064\064\064\064\064\064\064\064\064\064\064"
"\064\000\377\365\374\365\365\365\365\001\236\365\000\000\001\000\000\000\000\000\000\000\000\000\000\001\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\064\064\064\064\064\064\064\064\153\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\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\000\000\000\000\000\000\000\153\153\153\153"
"\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\153\337\266\266\266\000"
"\000\000\000\000\000\000\377\377\377\377\377\000\000\000\000\000\000\000\100\377\377\350\350\000\000\350\350\350\350\350\350\350\350\001\000\000\000\000\000\000"
"\036\103\012\072\103\365\000\000\000\000\000\000\000\000\000\377\377\377\350\350\350\350\350\350\350\350\350\350\350\350\350\350\254\350\350\350\350\354\350\350"
"\350\350\350\001\000\000\000\000\000\000\036\103\012\072\103\103\000\100\116\000\000\000\000\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\050\000\050\050\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\001\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\004\000\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032"
"\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032\032"
"\032\032\032\032\032\032\032\032\032\032\032\032\032\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\032\032\032\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\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\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\377\377\377\377\377\377\377\000\177\377\377\377\046\000\000\000\000\000\000\027\027\027"
"\027\027\027\027\027\027\027\027\027\000\027\027\027\027\000\004\000\000\000\000\000\135\000\044\103\000\000\377\377\377\377\377\103\377\364\377\364",
2157, DATA_MODE, -1, 1, ZINT_ERROR_TOO_LONG
}, /* #300 (#3) Andre Maute */
/* 11*/ { BARCODE_AZTEC,
"\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\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"
"\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\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"
"\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\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"
"\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\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"
"\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\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"
"\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\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"
"\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\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"
"\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\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"
"\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",
996, DATA_MODE, 2, -1, 0
}, /* Padding 11 example causing issue with ZXing-C++ */
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;