ref: bc914e674b0220b98a79fe8ee5329b7bd1b7257d
parent: 429d7cdce99df7b26eb6f15b819be98074f48695
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 2 09:00:31 EST 2014
Support line continuation escapes in string literals.
--- a/js-lex.c
+++ b/js-lex.c
@@ -230,34 +230,43 @@
return TK_NUMBER;
}
-static inline int lexescape(const char **sp)
+static inline int lexescape(js_State *J, const char **sp)
{
int c = GET();
int x = 0;
+ if (isnewline(c)) {
+ if (c == '\r' && PEEK() == '\n')
+ NEXT();
+ return 0;
+ }
+
switch (c) {
- case '0': return 0;
case 'u':
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK() << 12;
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK() << 8;
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK() << 4;
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK();
- return x;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK() << 12;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK() << 8;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK() << 4;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK();
+ textpush(J, x);
+ break;
case 'x':
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK() << 4;
- if (!ishex(PEEK())) return x; else x |= NEXTPEEK();
- return x;
- case '\'': return '\'';
- case '"': return '"';
- case '\\': return '\\';
- case 'b': return '\b';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 't': return '\t';
- case 'v': return '\v';
- default: return c;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK() << 4;
+ if (!ishex(PEEK())) return 1; else x |= NEXTPEEK();
+ textpush(J, x);
+ break;
+ case '0': textpush(J, 0); break;
+ case '\\': textpush(J, '\\'); break;
+ case '\'': textpush(J, '\''); break;
+ case '"': textpush(J, '"'); break;
+ case 'b': textpush(J, '\b'); break;
+ case 'f': textpush(J, '\f'); break;
+ case 'n': textpush(J, '\n'); break;
+ case 'r': textpush(J, '\r'); break;
+ case 't': textpush(J, '\t'); break;
+ case 'v': textpush(J, '\v'); break;
+ default: textpush(J, c); break;
}
+ return 0;
}
static inline int lexstring(js_State *J, const char **sp, int q)
@@ -269,9 +278,12 @@
while (c != q) {
if (c == 0 || isnewline(c))
return syntaxerror(J, "string not terminated");
- if (c == '\\')
- c = lexescape(sp);
- textpush(J, c);
+ if (c == '\\') {
+ if (lexescape(J, sp))
+ return syntaxerror(J, "malformed escape sequence");
+ } else {
+ textpush(J, c);
+ }
c = GET();
}