From 610f04beeb8d22d7a2d28003ea594c31e5c481d9 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Thu, 5 Sep 2024 15:24:17 +0200 Subject: [PATCH] Fix condition for assuming at EOF Part of that condition's purpose is to ensure that we read the correct lexer state; but it's possible now for the fstack to be non-empty *before* the lexer state is registered, i.e. if there is an error in the function that registers it. This causes a NULL pointer deref. --- include/asm/lexer.hpp | 1 + src/asm/fstack.cpp | 2 +- src/asm/lexer.cpp | 4 ++++ test/asm/nonexist-include.asm | 1 + test/asm/nonexist-include.err | 3 +++ test/asm/notexist.err | 4 ++++ test/asm/test.sh | 9 +++++---- 7 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/asm/nonexist-include.asm create mode 100644 test/asm/nonexist-include.err create mode 100644 test/asm/notexist.err diff --git a/include/asm/lexer.hpp b/include/asm/lexer.hpp index a9abc0fe..a282bbe9 100644 --- a/include/asm/lexer.hpp +++ b/include/asm/lexer.hpp @@ -131,6 +131,7 @@ static inline void lexer_SetGfxDigits(char const digits[4]) { gfxDigits[3] = digits[3]; } +bool lexer_AtTopLevel(); void lexer_RestartRept(uint32_t lineNo); void lexer_Init(); void lexer_SetMode(LexerMode mode); diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index 6e0d4db7..551d2534 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -73,7 +73,7 @@ std::string const &FileStackNode::dump(uint32_t curLineNo) const { } void fstk_DumpCurrent() { - if (contextStack.empty()) { + if (lexer_AtTopLevel()) { fputs("at top level", stderr); return; } diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 360b166b..0ddc42a0 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -338,6 +338,10 @@ static bool isWhitespace(int c) { static LexerState *lexerState = nullptr; static LexerState *lexerStateEOL = nullptr; +bool lexer_AtTopLevel() { + return lexerState == nullptr; +} + void LexerState::clear(uint32_t lineNo_) { mode = LEXER_NORMAL; atLineStart = true; // yylex() will init colNo due to this diff --git a/test/asm/nonexist-include.asm b/test/asm/nonexist-include.asm new file mode 100644 index 00000000..f818c834 --- /dev/null +++ b/test/asm/nonexist-include.asm @@ -0,0 +1 @@ +INCLUDE "nonexist-include.inc" diff --git a/test/asm/nonexist-include.err b/test/asm/nonexist-include.err new file mode 100644 index 00000000..50d7c6e4 --- /dev/null +++ b/test/asm/nonexist-include.err @@ -0,0 +1,3 @@ +error: nonexist-include.asm(1): + Unable to open included file 'nonexist-include.inc': No such file or directory +error: Assembly aborted (1 error)! diff --git a/test/asm/notexist.err b/test/asm/notexist.err new file mode 100644 index 00000000..fce6c89f --- /dev/null +++ b/test/asm/notexist.err @@ -0,0 +1,4 @@ +error: at top level: + Failed to stat file "notexist.asm": No such file or directory +FATAL: at top level: + Failed to open main file diff --git a/test/asm/test.sh b/test/asm/test.sh index 7d1069e2..33edcd20 100755 --- a/test/asm/test.sh +++ b/test/asm/test.sh @@ -60,13 +60,13 @@ else rm -f version.asm fi -for i in *.asm; do +for i in *.asm notexist.asm; do flags=${i%.asm}.flags RGBASMFLAGS=-Weverything if [ -f "$flags" ]; then RGBASMFLAGS="$(head -n 1 "$flags")" # Allow other lines to serve as comments fi - for variant in '' '.pipe'; do + for variant in '' ' piped'; do (( tests++ )) echo "${bold}${green}${i%.asm}${variant}...${rescolors}${resbold}" if [ -e "${i%.asm}.out" ]; then @@ -85,8 +85,9 @@ for i in *.asm; do desired_errput=$desired_errname else # `include-recursion.asm` refers to its own name inside the test code. - # Skip testing with stdin input for that file. - if [ "$i" = "include-recursion.asm" ]; then + # "notexist" doesn't exist, so there's no point in trying to `cat` it. + # Skip testing with stdin input for those file. + if [[ "$i" = include-recursion.asm || "$i" = notexist.asm ]]; then continue fi