From be2572edca1eb97f5ca801d4e4380e757b04f314 Mon Sep 17 00:00:00 2001 From: Rangi Date: Tue, 20 Apr 2021 09:37:18 -0400 Subject: [PATCH] Track nested interpolation depth even outside string literals Fixes #837 --- src/asm/lexer.c | 11 +++++++++++ test/asm/nested-interpolation-recursion.asm | 5 ++--- test/asm/nested-interpolation-recursion.err | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 867ef557..b830cc17 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -1280,6 +1280,14 @@ static char const *readInterpolation(unsigned int depth) char symName[MAXSYMLEN + 1]; size_t i = 0; struct FormatSpec fmt = fmt_NewSpec(); + bool disableInterpolation = lexerState->disableInterpolation; + + /* + * In a context where `lexerState->disableInterpolation` is true, `peek` will expand + * nested interpolations itself, which can lead to stack overflow. This lets + * `readInterpolation` handle its own nested expansions, increasing `depth` each time. + */ + lexerState->disableInterpolation = true; for (;;) { int c = peek(); @@ -1320,6 +1328,9 @@ static char const *readInterpolation(unsigned int depth) } symName[i] = '\0'; + /* Don't return before `lexerState->disableInterpolation` is reset! */ + lexerState->disableInterpolation = disableInterpolation; + static char buf[MAXSTRLEN + 1]; struct Symbol const *sym = sym_FindScopedSymbol(symName); diff --git a/test/asm/nested-interpolation-recursion.asm b/test/asm/nested-interpolation-recursion.asm index 9cbf2a81..cda9563c 100644 --- a/test/asm/nested-interpolation-recursion.asm +++ b/test/asm/nested-interpolation-recursion.asm @@ -1,3 +1,2 @@ -def s equs "s" -; 65 nested {}s, recursion limit is 64 -println "{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{s}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}" +; 128 nested {}s, recursion limit is 64 +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{s}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} diff --git a/test/asm/nested-interpolation-recursion.err b/test/asm/nested-interpolation-recursion.err index aeaa45e7..1d3614dd 100644 --- a/test/asm/nested-interpolation-recursion.err +++ b/test/asm/nested-interpolation-recursion.err @@ -1,2 +1,2 @@ -FATAL: nested-interpolation-recursion.asm(3): +FATAL: nested-interpolation-recursion.asm(2): Recursion limit (64) exceeded