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:
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)