shithub: libmujs

Download patch

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();
 	}