From b4f585e70eca236ca97e53ef487cea9a3ab5e78a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 29 Sep 2018 15:43:39 -0700 Subject: [PATCH] lexer: Fix buffer overread in journaling when source does not end in \n. An earlier commit removed the requirement that a source file ends in \n, but the lexer still made that assumption. This is intended to fix the problem. (Probably, some new tests should be added.) Thanks to John Darrington for reporting the problem. Fixes: e0f9210e814d ("lexer: Add support for embedded \0 bytes and missing trailing new-line.") --- src/language/lexer/lexer.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index fb45465f19..98cf8ec298 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -1414,20 +1414,30 @@ lex_source_get__ (const struct lex_source *src_) } for (int i = 0; i < n_lines; i++) { + /* Beginning of line. */ const char *line = &src->buffer[src->journal_pos - src->tail]; - const char *newline = rawmemchr (line, '\n'); - size_t line_len = newline - line; - if (line_len > 0 && line[line_len - 1] == '\r') - line_len--; - char *syntax = malloc (line_len + 2); - memcpy (syntax, line, line_len); - syntax[line_len] = '\n'; - syntax[line_len + 1] = '\0'; + /* Calculate line length, including \n or \r\n end-of-line if present. */ + size_t max_len = state.line_pos - src->journal_pos; + const char *newline = memchr (line, '\n', max_len); + size_t line_len = newline ? newline - line + 1 : max_len; + + /* Calculate line length excluding end-of-line. */ + size_t copy_len = line_len; + if (copy_len > 0 && line[copy_len - 1] == '\n') + copy_len--; + if (copy_len > 0 && line[copy_len - 1] == '\r') + copy_len--; + + /* Make a copy of the line with \n end-of-line and null terminator. */ + char *syntax = xmalloc (copy_len + 2); + memcpy (syntax, line, copy_len); + syntax[copy_len] = '\n'; + syntax[copy_len + 1] = '\0'; text_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX, syntax)); - src->journal_pos += newline - line + 1; + src->journal_pos += line_len; } token->token_len = state.seg_pos - src->seg_pos; -- 2.30.2