From bad66e54fad5c9d3773d30ae14eda94db44b4894 Mon Sep 17 00:00:00 2001 From: dbrotz <43593771+dbrotz@users.noreply.github.com> Date: Sat, 1 Dec 2018 07:10:59 -0800 Subject: [PATCH 1/4] Fix buffer overflow when file ends with \ --- src/asm/lexer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 20b6690a..17ff26b4 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -145,7 +145,7 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) size = ftell(f); fseek(f, 0, SEEK_SET); - pBuffer->pBufferRealStart = malloc(size + 2 + SAFETYMARGIN); + pBuffer->pBufferRealStart = malloc(size + 3 + SAFETYMARGIN); if (pBuffer->pBufferRealStart == NULL) fatalerror("%s: Out of memory for buffer!", __func__); @@ -156,8 +156,9 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f); pBuffer->pBuffer[size] = '\n'; - pBuffer->pBuffer[size + 1] = 0; - pBuffer->nBufferSize = size + 1; + pBuffer->pBuffer[size + 1] = '\n'; /* in case the file ends with \ */ + pBuffer->pBuffer[size + 2] = 0; + pBuffer->nBufferSize = size + 2; /* Convert all line endings to LF and spaces */ From a060f135b83a1574e20a52d8aef8b21dd193238a Mon Sep 17 00:00:00 2001 From: dbrotz <43593771+dbrotz@users.noreply.github.com> Date: Sun, 2 Dec 2018 20:43:20 -0800 Subject: [PATCH 2/4] Only add newlines to file if necessary --- src/asm/lexer.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 17ff26b4..77a53716 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -155,10 +155,7 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f); - pBuffer->pBuffer[size] = '\n'; - pBuffer->pBuffer[size + 1] = '\n'; /* in case the file ends with \ */ - pBuffer->pBuffer[size + 2] = 0; - pBuffer->nBufferSize = size + 2; + pBuffer->pBuffer[size] = 0; /* Convert all line endings to LF and spaces */ @@ -219,6 +216,30 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) } } + pBuffer->nBufferSize = size; + + /* Add newline if file doesn't end with one */ + if (size == 0 || pBuffer->pBuffer[size - 1] != '\n') { + pBuffer->pBuffer[pBuffer->nBufferSize] = '\n'; + pBuffer->nBufferSize++; + } + + /* Add newline if \ will eat the last newline */ + if (pBuffer->nBufferSize >= 2) { + size_t pos = pBuffer->nBufferSize - 2; + + /* Skip spaces */ + while (pos > 0 && pBuffer->pBuffer[pos] == ' ') + pos--; + + if (pBuffer->pBuffer[pos] == '\\') { + pBuffer->pBuffer[pBuffer->nBufferSize] = '\n'; + pBuffer->nBufferSize++; + } + } + + pBuffer->pBuffer[pBuffer->nBufferSize] = 0; + pBuffer->oAtLineStart = 1; return pBuffer; } From 6c1ec59a5b7fd1a41d3bb8e213f0c5a8c4c7f3f1 Mon Sep 17 00:00:00 2001 From: dbrotz <43593771+dbrotz@users.noreply.github.com> Date: Wed, 5 Dec 2018 01:32:06 -0800 Subject: [PATCH 3/4] Use separate function to append newlines --- src/asm/lexer.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 77a53716..30a940a7 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -6,6 +6,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include #include @@ -110,6 +111,21 @@ void yy_delete_buffer(YY_BUFFER_STATE buf) free(buf); } +/* + * Maintains the following invariants: + * 1. nBufferSize < capacity + * 2. The buffer is terminated with 0 + * 3. nBufferSize is the size without the terminator + */ +static void yy_buffer_append(YY_BUFFER_STATE buf, uint32_t capacity, char c) +{ + assert(buf->pBuffer[buf->nBufferSize] == 0); + assert(buf->nBufferSize + 1 < capacity); + + buf->pBuffer[buf->nBufferSize++] = c; + buf->pBuffer[buf->nBufferSize] = 0; +} + YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size) { YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state)); @@ -145,7 +161,10 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) size = ftell(f); fseek(f, 0, SEEK_SET); - pBuffer->pBufferRealStart = malloc(size + 3 + SAFETYMARGIN); + /* Give extra room for 2 newlines and terminator */ + uint32_t capacity = size + 3; + + pBuffer->pBufferRealStart = malloc(capacity + SAFETYMARGIN); if (pBuffer->pBufferRealStart == NULL) fatalerror("%s: Out of memory for buffer!", __func__); @@ -156,6 +175,7 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f); pBuffer->pBuffer[size] = 0; + pBuffer->nBufferSize = size; /* Convert all line endings to LF and spaces */ @@ -216,13 +236,9 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) } } - pBuffer->nBufferSize = size; - /* Add newline if file doesn't end with one */ - if (size == 0 || pBuffer->pBuffer[size - 1] != '\n') { - pBuffer->pBuffer[pBuffer->nBufferSize] = '\n'; - pBuffer->nBufferSize++; - } + if (size == 0 || pBuffer->pBuffer[size - 1] != '\n') + yy_buffer_append(pBuffer, capacity, '\n'); /* Add newline if \ will eat the last newline */ if (pBuffer->nBufferSize >= 2) { @@ -232,14 +248,10 @@ YY_BUFFER_STATE yy_create_buffer(FILE *f) while (pos > 0 && pBuffer->pBuffer[pos] == ' ') pos--; - if (pBuffer->pBuffer[pos] == '\\') { - pBuffer->pBuffer[pBuffer->nBufferSize] = '\n'; - pBuffer->nBufferSize++; - } + if (pBuffer->pBuffer[pos] == '\\') + yy_buffer_append(pBuffer, capacity, '\n'); } - pBuffer->pBuffer[pBuffer->nBufferSize] = 0; - pBuffer->oAtLineStart = 1; return pBuffer; } From 5a3c12cc6bc1e102a063081f98e4d342053a3317 Mon Sep 17 00:00:00 2001 From: dbrotz <43593771+dbrotz@users.noreply.github.com> Date: Thu, 6 Dec 2018 23:27:41 -0800 Subject: [PATCH 4/4] Add test for file ending with \ --- test/asm/line-continuation.asm | 1 + test/asm/line-continuation.out | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 test/asm/line-continuation.asm create mode 100644 test/asm/line-continuation.out diff --git a/test/asm/line-continuation.asm b/test/asm/line-continuation.asm new file mode 100644 index 00000000..5474f368 --- /dev/null +++ b/test/asm/line-continuation.asm @@ -0,0 +1 @@ +foo @bar\ \ No newline at end of file diff --git a/test/asm/line-continuation.out b/test/asm/line-continuation.out new file mode 100644 index 00000000..1d1dd81b --- /dev/null +++ b/test/asm/line-continuation.out @@ -0,0 +1,2 @@ +ERROR: line-continuation.asm(2) -> @(-1): + Macro '@' not defined