mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
PDF417: fix out-of-bounds crash in pdf_text_submode_length()
by changing
`pdf_num_stay()` to not call it if previous/next block is BYT; also extend `pdf_asciix[]` to full 256 byte range (defensive & also can use directly rather than checking range, ticket #300, props Andre Maute
This commit is contained in:
parent
323b34502b
commit
4b57fb8021
@ -109,6 +109,8 @@ Bugs
|
||||
- GUI: fix not enabling font combo "Small Bold (vector only)" by default
|
||||
- CODEONE: fix S/T quiet zone 1X bottom (props BWIPP issue #245 doc)
|
||||
- EAN-2/EAN-5: fix `BARCODE_BIND_TOP/BIND/BOX` output
|
||||
- PDF417: fix out-of-bounds crash in `pdf_text_submode_length()`, ticket #300,
|
||||
props Andre Maute
|
||||
|
||||
|
||||
Version 2.12.0 (2022-12-12)
|
||||
|
@ -93,7 +93,7 @@ static const char *pdf_mode_str(const int mode) {
|
||||
/* text mode processing tables */
|
||||
|
||||
/* TEX sub-mode assignments */
|
||||
static const char pdf_asciix[127] = {
|
||||
static const char pdf_asciix[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 00-07 */
|
||||
0, T_MXPNC, T_PUNCT, 0, 0, T_MXPNC, 0, 0, /* 08-0F .<HT><LF>..<CR>.. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */
|
||||
@ -109,7 +109,11 @@ static const char pdf_asciix[127] = {
|
||||
T_PUNCT, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, /* 60-67 `abcdefg */
|
||||
T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, /* 68-6F hijklmno */
|
||||
T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, T_LOWER, /* 70-77 pqrstuvw */
|
||||
T_LOWER, T_LOWER, T_LOWER, T_PUNCT, T_PUNCT, T_PUNCT, T_PUNCT /* 78-7E xyz{|}~ */
|
||||
T_LOWER, T_LOWER, T_LOWER, T_PUNCT, T_PUNCT, T_PUNCT, T_PUNCT, 0, /* 78-7E xyz{|}~D */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80-9F*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*A0-BF*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*C0-DF*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*E0-FF*/
|
||||
};
|
||||
|
||||
/* TEX sub-mode values */
|
||||
@ -152,7 +156,7 @@ static int pdf_quelmode(const unsigned char codeascii) {
|
||||
if (z_isdigit(codeascii)) {
|
||||
return PDF_NUM;
|
||||
}
|
||||
if (codeascii < 127 && pdf_asciix[codeascii]) {
|
||||
if (pdf_asciix[codeascii]) {
|
||||
return PDF_TEX;
|
||||
}
|
||||
/* 876 */
|
||||
@ -233,6 +237,7 @@ static int pdf_text_submode_length(const unsigned char chaine[], const int start
|
||||
int j, indexlistet, curtable = *p_curtable, listet[PDF_MAX_LEN], chainet[PDF_MAX_LEN], wnet = 0;
|
||||
|
||||
for (indexlistet = 0; indexlistet < length; indexlistet++) {
|
||||
assert(pdf_asciix[chaine[start + indexlistet]]); /* Should only be dealing with TEX */
|
||||
listet[indexlistet] = pdf_asciix[chaine[start + indexlistet]];
|
||||
}
|
||||
|
||||
@ -283,7 +288,7 @@ static int pdf_text_submode_length(const unsigned char chaine[], const int start
|
||||
|
||||
/* Whether to stay in numeric mode or not */
|
||||
static int pdf_num_stay(const unsigned char *chaine, const int indexliste, int liste[3][PDF_MAX_LEN], const int i) {
|
||||
int curtable, last_len, last_ml, next_len, num_cws, tex_cws;
|
||||
int curtable, not_tex, last_len, last_ml, next_len, num_cws, tex_cws;
|
||||
|
||||
if (liste[0][i] >= 13 || (indexliste == 1 && liste[0][i] > 5)) {
|
||||
return 1;
|
||||
@ -293,15 +298,17 @@ static int pdf_num_stay(const unsigned char *chaine, const int indexliste, int l
|
||||
}
|
||||
|
||||
curtable = T_ALPHA;
|
||||
last_len = i == 0 ? 0 : pdf_text_submode_length(chaine, liste[2][i - 1], liste[0][i - 1], &curtable);
|
||||
not_tex = i == 0 || liste[1][i - 1] == PDF_BYT;
|
||||
last_len = not_tex ? 0 : pdf_text_submode_length(chaine, liste[2][i - 1], liste[0][i - 1], &curtable);
|
||||
last_ml = curtable == T_MIXED;
|
||||
|
||||
curtable = T_ALPHA; /* Next len if after NUM, sub-mode will be alpha */
|
||||
next_len = i == indexliste - 1 ? 0 : pdf_text_submode_length(chaine, liste[2][i + 1], liste[0][i + 1], &curtable);
|
||||
not_tex = i == indexliste - 1 || liste[1][i + 1] == PDF_BYT;
|
||||
next_len = not_tex ? 0 : pdf_text_submode_length(chaine, liste[2][i + 1], liste[0][i + 1], &curtable);
|
||||
num_cws = ((last_len + 1) >> 1) + 1 + 4 + (liste[0][i] > 11) + 1 + ((next_len + 1) >> 1);
|
||||
|
||||
curtable = T_MIXED; /* Next len if stay TEX, sub-mode will be mixed */
|
||||
next_len = i == indexliste - 1 ? 0 : pdf_text_submode_length(chaine, liste[2][i + 1], liste[0][i + 1], &curtable);
|
||||
next_len = not_tex ? 0 : pdf_text_submode_length(chaine, liste[2][i + 1], liste[0][i + 1], &curtable);
|
||||
tex_cws = (last_len + !last_ml + liste[0][i] + next_len + 1) >> 1;
|
||||
|
||||
if (num_cws > tex_cws) {
|
||||
@ -505,7 +512,7 @@ static void pdf_textprocess_minimal(int *chainemc, int *p_mclength, const unsign
|
||||
const int from = liste[2][i];
|
||||
for (j = 0; j < liste[0][i]; j++) {
|
||||
const int c = chaine[from + j];
|
||||
const int t_table = c < 127 ? pdf_asciix[c] : 0;
|
||||
const int t_table = pdf_asciix[c];
|
||||
if (!t_table) { /* BYT Shift? */
|
||||
if (wnet & 1) {
|
||||
chainet[wnet++] = 29; /* PS or AL (T_PUNCT) */
|
||||
@ -665,7 +672,7 @@ INTERNAL void pdf_numbprocess_test(int *chainemc, int *p_mclength, const unsigne
|
||||
static int pdf_table_length(const unsigned char source[], const int length, const int position, const int t_table) {
|
||||
int i;
|
||||
|
||||
for (i = position; i < length && source[i] < 127 && (pdf_asciix[source[i]] & t_table); i++);
|
||||
for (i = position; i < length && (pdf_asciix[source[i]] & t_table); i++);
|
||||
|
||||
return i - position;
|
||||
}
|
||||
@ -857,7 +864,7 @@ static void pdf_addEdge(const unsigned char *source, const int length, struct pd
|
||||
static void pdf_addEdges(const unsigned char source[], const int length, const int lastmode, struct pdf_edge *edges,
|
||||
const int from, struct pdf_edge *previous) {
|
||||
const unsigned char c = source[from];
|
||||
const int t_table = c < 127 ? pdf_asciix[c] : 0;
|
||||
const int t_table = pdf_asciix[c];
|
||||
|
||||
if (t_table & T_ALPHA) {
|
||||
const int len = pdf_table_length(source, length, from, T_ALPHA);
|
||||
|
@ -4775,7 +4775,7 @@ static void test_encode_segs(const testCtx *const p_ctx) {
|
||||
testFinish();
|
||||
}
|
||||
|
||||
/* #181 Nico Gunkel OSS-Fuzz */
|
||||
/* #181 Nico Gunkel OSS-Fuzz and #300 Andre Maute */
|
||||
static void test_fuzz(const testCtx *const p_ctx) {
|
||||
int debug = p_ctx->debug;
|
||||
|
||||
@ -5296,6 +5296,35 @@ static void test_fuzz(const testCtx *const p_ctx) {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ",
|
||||
251, -1, ZINT_ERROR_TOO_LONG },
|
||||
/*28*/ { BARCODE_PDF417COMP, DATA_MODE | FAST_MODE,
|
||||
"\000\000\000\377\377\010\002\000\000\033\005\031\000\000\002\000\000\000\000\101\101\101\101\101\101\101\101\000\000\000\000\000\000\000\374\000\101\101\101\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\323\000\000\000\000\000\010\000\000\000\000\165\000\000\000\000\000\000\000\000\000\000\000\000\056"
|
||||
"\000\000\000\000\000\000\000\000\000\000\100\000\000\101\101\101\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\323\000\000\000\000\000\010\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\323\000\000\000\000\000\010\000\000\000\000\165\000\000\000\000\000\000\000\000\000\000\000\000\056\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\101\101\101\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\323\000\010\000\000\000\010\000\000\000\000\165\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\056\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\375\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\101\101\101\101\101\101\101\101\101\101\101\055\101\101\101\101\101\101\101\101\101"
|
||||
"\101\101\101\060\151\003\000\000\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\137\101\101\101\101\101\101\101\101\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\101\101\101\101\101\101\101\101\101\101\000\000\000\000\000\000\000\000\000\070\000\000\000\000\000\000\000"
|
||||
"\000\000\000\377\377\010\002\000\000\033\005\031\000\000\002\000\000\000\000\101\101\101\101\101\101\101\101\000\000\000\000\000\000\000\374\000\101\101\101\000"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\323\000\000\000\000\000\010\000\000\000\000\165\000\000\000\000\000\000\000\000\000\000\000\000\056"
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\375\000\000\000\000\000\000\000\000\000\000\000\000\000\040\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\375\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\101\101\101\101\101\101\101\101\101\101\101\101\101\055\101\101\101\101\101\101\101\101\101"
|
||||
"\101\101\101\060\151\003\000\000\101\101\101\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\373\377\377\377\377\060"
|
||||
"\060\060\060\060\060\060\060\060\060\060\060\051\060\060\060\060\060\060\377\377\377\377\000\000\000\000\377\161\000\151\151\250\122\141\012\377\377\021\021\021"
|
||||
"\021\021\021\161\021\000\324\324\324\324\324\324\324\324\324\324\324\000\000\000\000\112\000\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324"
|
||||
"\320\324\324\324\324\021\176\012\000\000\000\000\000\000\324\324\324\324\324\324\324\101\101\101\101\101\101\101\352\352\352\352\352\352\352\352\352\352\352\352"
|
||||
"\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\352\000"
|
||||
"\000\000\000\000\101\101\101\101\101\101\101\101\101\101\101\101\101\137\101\101\101\101\101\101\101\101\000\000\000\000\000\000\000\000\000\000\000\000\101\101"
|
||||
"\101\101\041\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\324\324\324\324\324\324\324\324\324\077\324\324\324\324\324\324\324\324\324\324"
|
||||
"\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\324\000\060\060\060\060\060"
|
||||
"\060\060\060\060\060\060\060\060\060\060\060\051\060\060\060\060\060\060\377\377\377\377\000\000\000\000\377\161\000\151\151\250\122\141\012\377\377\021\021\021"
|
||||
"\021\021\021\161\021\000\324\324\324\324\324\324\324\324\324\324\324\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\137\101\101\101\101\101"
|
||||
"\101\000\000\000\000\374\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\323\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000\323\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
|
||||
"\000\000\000\000\000\000\000\000",
|
||||
1048, 0, 0 }, /* #300 Andre Maute */
|
||||
};
|
||||
int data_size = ARRAY_SIZE(data);
|
||||
int i, length, ret;
|
||||
|
Loading…
Reference in New Issue
Block a user