ref: e732e73904098e6063403a6516c29fe536534549
parent: 19b99b76f3636603e12eaefee2254a81449be0ec
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Nov 13 04:03:27 EST 2021
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.
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -183,11 +183,11 @@
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] == ' ')
@@ -194,7 +194,6 @@
--bp, ++bufsiz;
while (s[1] == ' ')
++s;
- case '#':
break;
case '\'':
delim = '\'';
@@ -219,21 +218,41 @@
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)