scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 90d8b7484070c487d7786ad4ff030c78938490da
parent 9052934936af914af5df2538244cd845193882a9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 13 Nov 2021 09:03:27 +0100

cc1: Escape " in stringizer operator

The stringizer operator works at the preprocessor level, and it means that
adding " at eh beginning and at the end can modify the structure of the code.
For this reason it is needed to escape the quotation marks within the expansion.

Diffstat:
Msrc/cmd/cc/cc1/cpp.c | 39+++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -183,18 +183,17 @@ parsepars(char *buffer, char **listp, int nargs) static size_t copymacro(char *buffer, char *s, size_t bufsiz, char *arglist[]) { - int delim, prevc, c, esc; + int delim, c, esc; char *p, *arg, *bp = buffer; size_t size; - for (prevc = '\0'; c = *s; prevc = c, ++s) { + for (; c = *s; ++s) { switch (c) { case '$': while (bp[-1] == ' ') --bp, ++bufsiz; while (s[1] == ' ') ++s; - case '#': break; case '\'': delim = '\''; @@ -219,21 +218,41 @@ copymacro(char *buffer, char *s, size_t bufsiz, char *arglist[]) bufsiz -= size; bp += size; break; + case '#': + arg = arglist[atoi(s += 2)]; + s += 2; + + if (bufsiz < 3) + goto expansion_too_long; + + *bp++ = '"'; + while ((c = *arg++) != '\0') { + if (c == '"') { + if (bufsiz < 3) + goto expansion_too_long; + *bp++ = '\\'; + *bp++ = '"'; + bufsiz -= 2; + } else { + if (bufsiz < 2) + goto expansion_too_long; + *bp++ = c; + bufsiz--; + } + } + *bp++ = '"'; + + break; case '@': - if (prevc == '#') - bufsiz -= 2; arg = arglist[atoi(++s)]; + s += 2; + size = strlen(arg); if (size > bufsiz) goto expansion_too_long; - if (prevc == '#') - *bp++ = '"'; memcpy(bp, arg, size); bp += size; - if (prevc == '#') - *bp++ = '"'; bufsiz -= size; - s += 2; break; default: if (bufsiz-- == 0)