Skip to content

Commit

Permalink
unescape: add boundaries check on utf-8 (oss-fuzz 22180)
Browse files Browse the repository at this point in the history
Signed-off-by: Eduardo Silva <eduardo@treasure-data.com>
  • Loading branch information
edsiper committed May 13, 2020
1 parent 05117e6 commit d6c4796
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/flb_unescape.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static int u8_wc_toutf8(char *dest, uint32_t ch)

/* assumes that src points to the character after a backslash
returns number of input characters processed */
static int u8_read_escape_sequence(const char *str, uint32_t *dest)
static int u8_read_escape_sequence(const char *str, int size, uint32_t *dest)
{
uint32_t ch;
char digs[9]="\0\0\0\0\0\0\0\0";
Expand All @@ -93,29 +93,32 @@ static int u8_read_escape_sequence(const char *str, uint32_t *dest)
i = 0;
do {
digs[dno++] = str[i++];
} while (octal_digit(str[i]) && dno < 3);
} while (i < size && octal_digit(str[i]) && dno < 3);
ch = strtol(digs, NULL, 8);
}
else if (str[0] == 'x') {
while (hex_digit(str[i]) && dno < 2) {
while (i < size && hex_digit(str[i]) && dno < 2) {
digs[dno++] = str[i++];
}
if (dno > 0)
if (dno > 0) {
ch = strtol(digs, NULL, 16);
}
}
else if (str[0] == 'u') {
while (hex_digit(str[i]) && dno < 4) {
while (i < size && hex_digit(str[i]) && dno < 4) {
digs[dno++] = str[i++];
}
if (dno > 0)
if (dno > 0) {
ch = strtol(digs, NULL, 16);
}
}
else if (str[0] == 'U') {
while (hex_digit(str[i]) && dno < 8) {
while (i < size && hex_digit(str[i]) && dno < 8) {
digs[dno++] = str[i++];
}
if (dno > 0)
if (dno > 0) {
ch = strtol(digs, NULL, 16);
}
}
*dest = ch;

Expand All @@ -128,6 +131,8 @@ int flb_unescape_string_utf8(const char *in_buf, int sz, char *out_buf)
char temp[4];
const char *end;
const char *next;
int size;


int count_out = 0;
int count_in = 0;
Expand Down Expand Up @@ -168,7 +173,14 @@ int flb_unescape_string_utf8(const char *in_buf, int sz, char *out_buf)
ch = '\r';
break;
default:
esc_in = u8_read_escape_sequence((in_buf + 1), &ch) + 1;
size = end - next;
if (size > 0) {
esc_in = u8_read_escape_sequence(next, size, &ch) + 1;
}
else {
ch = (uint32_t) *in_buf;
esc_in = 1;
}
}
}
else {
Expand Down

0 comments on commit d6c4796

Please sign in to comment.