diff --git a/src/link/script.c b/src/link/script.c index dacc46cb..6c985ad5 100644 --- a/src/link/script.c +++ b/src/link/script.c @@ -19,7 +19,7 @@ #include "extern/err.h" -FILE * linkerScript; +FILE *linkerScript; char *includeFileName; static uint32_t lineNo; @@ -223,12 +223,28 @@ static struct LinkerScriptToken *nextToken(void) do { curchar = readChar(linkerScript); - if (curchar == EOF || isNewline(curchar)) + if (curchar == EOF || isNewline(curchar)) { errx(1, "%s(%" PRIu32 "): Unterminated string", linkerScriptName, lineNo); - else if (curchar == '"') + } else if (curchar == '"') { /* Quotes force a string termination */ curchar = '\0'; + } else if (curchar == '\\') { + /* Backslashes are escape sequences */ + curchar = readChar(linkerScript); + if (curchar == EOF || isNewline(curchar)) + errx(1, "%s(%" PRIu32 "): Unterminated string", + linkerScriptName, lineNo); + else if (curchar == 'n') + curchar = '\n'; + else if (curchar == 'r') + curchar = '\r'; + else if (curchar == 't') + curchar = '\t'; + else if (curchar != '\\' && curchar != '"') + errx(1, "%s(%" PRIu32 "): Illegal character escape", + linkerScriptName, lineNo); + } if (size >= capacity || token.attr.string == NULL) { capacity *= 2; diff --git a/test/link/linkerscript-escapes-test.link b/test/link/linkerscript-escapes-test.link new file mode 100644 index 00000000..d3c44f1f --- /dev/null +++ b/test/link/linkerscript-escapes-test.link @@ -0,0 +1,3 @@ +ROM0 + "A\"B\tC\rD\nE" + "in\{valid" diff --git a/test/link/linkerscript-escapes-test.out b/test/link/linkerscript-escapes-test.out new file mode 100644 index 00000000..aa3fd48f --- /dev/null +++ b/test/link/linkerscript-escapes-test.out @@ -0,0 +1 @@ +error: ./linkerscript-escapes-test.link(3): Illegal character escape diff --git a/test/link/linkerscript-escapes.asm b/test/link/linkerscript-escapes.asm new file mode 100644 index 00000000..a379c665 --- /dev/null +++ b/test/link/linkerscript-escapes.asm @@ -0,0 +1,4 @@ +SECTION "A\"B\tC\rD\nE", ROM0 +DS $1000 +SECTION "in\{valid", ROM0 +DS $1000