Avoid producing invalid string literals in #pragma expand output.

Previously, the characters ", /, and ? within string literals were not escaped in #pragma expand output, which could result in them being erroneously interpreted as ending the string literal, starting an escape sequence, or being part of a trigraph (respectively). Also, escape sequences were output in hexadecimal format. Since there is no length limit on hexadecimal escape sequences, this could result in subsequent characters in the string being interpreted as part of the escape sequence.

This fixes the issues by escaping the characters ", /, and ?, and by using three-digit octal escape sequences rather than hexadecimal ones.
This commit is contained in:
Stephen Heumann 2018-09-01 16:11:18 -05:00
parent a6f1211ee6
commit 9ff3407c60
1 changed files with 9 additions and 22 deletions

View File

@ -659,23 +659,6 @@ var
ch: char; {work character}
i: integer; {loop counter}
procedure PrintHexDigit(i: integer);
{ Print a digit as a hex character }
{ }
{ Parameters: }
{ i: value to print in least significant 4 bits }
begin {PrintHexDigit}
i := i & $000F;
if i < 10 then
write(chr(i | ord('0')))
else
write(chr(i + ord('A') - 10));
end; {PrintHexDigit}
begin {PrintToken}
case token.kind of
typedef,
@ -693,12 +676,16 @@ case token.kind of
write('"');
for i := 1 to token.sval^.length do begin
ch := token.sval^.str[i];
if ch in [' '..'~'] then
write(ch)
if ch in [' '..'~'] then begin
if ch in ['"','\','?'] then
write('\');
write(ch);
end {if}
else begin
write('\x0');
PrintHexDigit(ord(ch)>>4);
PrintHexDigit(ord(ch));
write('\');
write((ord(ch)>>6):1);
write(((ord(ch)>>3) & $0007):1);
write((ord(ch) & $0007):1);
end; {else}
end; {for}
write('"');