JavaScriptCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jan 2008 06:44:22 +0000 (06:44 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jan 2008 06:44:22 +0000 (06:44 +0000)
        Reviewed by Eric.

        - fix for http://bugs.webkit.org/show_bug.cgi?id=16695
          JSC allows non-identifier codepoints in identifiers (affects Acid3)

        Test: fast/js/kde/parse.html

        * kjs/lexer.cpp:
        (KJS::Lexer::lex): Added additional states to distinguish Unicode escapes at the
        start of identifiers from ones inside identifiers. Rejected characters that don't pass
        the isIdentStart and isIdentPart tests.
        (KJS::Lexer::convertUnicode): Removed incorrect FIXME comment.

        * kjs/lexer.h: Added new states to distinguish \u escapes at the start of identifiers
        from \u escapes inside identifiers.

LayoutTests:

        Reviewed by Eric.

        - test for http://bugs.webkit.org/show_bug.cgi?id=16695
          JSC allows non-identifier codepoints in identifiers (affects Acid3)

        * fast/js/kde/parse-expected.txt: Updated.
        * fast/js/kde/resources/parse.js: Added tests that cover both the
        non-ASCII characters themselves and the same characters parsed as
        \u sequences.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@29075 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/lexer.cpp
JavaScriptCore/kjs/lexer.h
LayoutTests/ChangeLog
LayoutTests/fast/js/kde/parse-expected.txt
LayoutTests/fast/js/kde/resources/parse.js

index 9a468e6b2c3d26a736f37ead44980bef61376a72..9e813e67b05755a923b9c2047d69e70d5b03c873 100644 (file)
@@ -1,3 +1,21 @@
+2008-01-01  Darin Adler  <darin@apple.com>
+
+        Reviewed by Eric.
+
+        - fix for http://bugs.webkit.org/show_bug.cgi?id=16695
+          JSC allows non-identifier codepoints in identifiers (affects Acid3)
+
+        Test: fast/js/kde/parse.html
+
+        * kjs/lexer.cpp:
+        (KJS::Lexer::lex): Added additional states to distinguish Unicode escapes at the
+        start of identifiers from ones inside identifiers. Rejected characters that don't pass
+        the isIdentStart and isIdentPart tests.
+        (KJS::Lexer::convertUnicode): Removed incorrect FIXME comment.
+
+        * kjs/lexer.h: Added new states to distinguish \u escapes at the start of identifiers
+        from \u escapes inside identifiers.
+
 2008-01-01  Darin Adler  <darin@apple.com>
 
         - rolled scope chain optimization out; it was breaking the world
index 4c088b48af68d827670aa12506d99d94d7f6f268..8cca3cb7f2687c8474d7a4c91403767a4984e664 100644 (file)
@@ -212,7 +212,7 @@ int Lexer::lex()
         record16(current);
         state = InIdentifierOrKeyword;
       } else if (current == '\\') {
-        state = InIdentifierUnicodeEscapeStart;
+        state = InIdentifierStartUnicodeEscapeStart;
       } else if (current == '0') {
         record8(current);
         state = InNum0;
@@ -341,7 +341,7 @@ int Lexer::lex()
       if (isIdentPart(current))
         record16(current);
       else if (current == '\\')
-        state = InIdentifierUnicodeEscapeStart;
+        state = InIdentifierPartUnicodeEscapeStart;
       else
         setDone(state == InIdentifierOrKeyword ? IdentifierOrKeyword : Identifier);
       break;
@@ -418,20 +418,45 @@ int Lexer::lex()
       } else
         setDone(Number);
       break;
-    case InIdentifierUnicodeEscapeStart:
+    case InIdentifierStartUnicodeEscapeStart:
       if (current == 'u')
-        state = InIdentifierUnicodeEscape;
+        state = InIdentifierStartUnicodeEscape;
       else
         setDone(Bad);
       break;
-    case InIdentifierUnicodeEscape:
-      if (isHexDigit(current) && isHexDigit(next1) && isHexDigit(next2) && isHexDigit(next3)) {
-        record16(convertUnicode(current, next1, next2, next3));
-        shift(3);
-        state = InIdentifier;
-      } else {
+    case InIdentifierPartUnicodeEscapeStart:
+      if (current == 'u')
+        state = InIdentifierPartUnicodeEscape;
+      else
+        setDone(Bad);
+      break;
+    case InIdentifierStartUnicodeEscape:
+      if (!isHexDigit(current) || !isHexDigit(next1) || !isHexDigit(next2) || !isHexDigit(next3)) {
         setDone(Bad);
+        break;
+      }
+      token = convertUnicode(current, next1, next2, next3).uc;
+      shift(3);
+      if (!isIdentStart(token)) {
+        setDone(Bad);
+        break;
+      }
+      record16(token);
+      state = InIdentifier;
+      break;
+    case InIdentifierPartUnicodeEscape:
+      if (!isHexDigit(current) || !isHexDigit(next1) || !isHexDigit(next2) || !isHexDigit(next3)) {
+        setDone(Bad);
+        break;
+      }
+      token = convertUnicode(current, next1, next2, next3).uc;
+      shift(3);
+      if (!isIdentPart(token)) {
+        setDone(Bad);
+        break;
       }
+      record16(token);
+      state = InIdentifier;
       break;
     default:
       ASSERT(!"Unhandled state in switch statement");
@@ -779,7 +804,6 @@ unsigned char Lexer::convertHex(int c1, int c2)
 
 KJS::UChar Lexer::convertUnicode(int c1, int c2, int c3, int c4)
 {
-  // FIXME: This conversion is lossy. See http://bugs.webkit.org/show_bug.cgi?id=4920.
   return KJS::UChar((convertHex(c1) << 4) + convertHex(c2),
                (convertHex(c3) << 4) + convertHex(c4));
 }
index bfaa888bb97f396c6707a61ca141350c2e1e96ac..595fbc866f241ccd77e6c25d9ccefda7a0978ede 100644 (file)
@@ -46,8 +46,10 @@ namespace KJS {
                  Identifier,
                  InIdentifierOrKeyword,
                  InIdentifier,
-                 InIdentifierUnicodeEscapeStart,
-                 InIdentifierUnicodeEscape,
+                 InIdentifierStartUnicodeEscapeStart,
+                 InIdentifierStartUnicodeEscape,
+                 InIdentifierPartUnicodeEscapeStart,
+                 InIdentifierPartUnicodeEscape,
                  InSingleLineComment,
                  InMultiLineComment,
                  InNum,
index ecc21081080681afc95cf4e99ed594d06d811f48..f0c36df363af318605fc55e2ab07d1aeaeac8220 100644 (file)
@@ -1,3 +1,15 @@
+2008-01-01  Darin Adler  <darin@apple.com>
+
+        Reviewed by Eric.
+
+        - test for http://bugs.webkit.org/show_bug.cgi?id=16695
+          JSC allows non-identifier codepoints in identifiers (affects Acid3)
+
+        * fast/js/kde/parse-expected.txt: Updated.
+        * fast/js/kde/resources/parse.js: Added tests that cover both the
+        non-ASCII characters themselves and the same characters parsed as
+        \u sequences.
+
 2008-01-01  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Darin.
index ecec077280334a7f2ee88eba3c211af3e71dd638..9f365553c12c48956d5bfeb231e65f8f9ac85548 100644 (file)
@@ -3,8 +3,15 @@ KDE JS Test
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS res is 11
-PASS caught is true
+PASS var éĀʯΈᢨ = 101; éĀʯΈᢨ; is 101
+PASS var f÷; threw exception SyntaxError: Parse error.
+PASS var \u0061 = 102; a is 102
+PASS var f\u0030 = 103; f0 is 103
+PASS var \u00E9\u0100\u02AF\u0388\u18A8 = 104; \u00E9\u0100\u02AF\u0388\u18A8; is 104
+PASS var f\u00F7; threw exception SyntaxError: Parse error.
+PASS var \u0030; threw exception SyntaxError: Parse error.
+PASS var test = { }; test.i= 0; test.i\u002b= 1; test.i; threw exception SyntaxError: Parse error.
+PASS var test = { }; test.i= 0; test.i+= 1; test.i; is 1
 PASS successfullyParsed is true
 
 TEST COMPLETE
index cdd8252e6a1dad13362bb56317987b3a13ce13be..ed42dac1e3a9d8479be8ac6d3dd8928c939852da 100644 (file)
@@ -22,24 +22,24 @@ c = 2
 c = 3 /* comment */
 d = 4
 
-// non-ascii identifier letters (not working copy of Mozilla?!)
-var ident = "";
-ident += "\u00E9"; // LATIN SMALL LETTER E WITH ACUTE
-ident += "\u0100"; // LATIN CAPITAL LETTER A WITH MACRON
-ident += "\u02af"; // LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
-ident += "\u0388"; // GREEK CAPITAL LETTER EPSILON WITH TONOS
-ident += "\u18A8"; // MONGOLIAN LETTER MANCHU ALI GALI BHA
-var code = "var " + ident + " = 11; " + ident + ";";
-var res = eval(code);
-shouldBe("res", "11");
-
-// invalid identifier letter
-var caught = false;
-try {
-  eval("var f\xf7;"); // 
-} catch (e) {
-  caught = true;
-}
-shouldBeTrue("caught");
+// non-ASCII identifier letters
+shouldBe("var \u00E9\u0100\u02AF\u0388\u18A8 = 101; \u00E9\u0100\u02AF\u0388\u18A8;", "101");
+
+// invalid identifier letters
+shouldThrow("var f\xF7;");
+
+// ASCII identifier characters as escape sequences
+shouldBe("var \\u0061 = 102; a", "102");
+shouldBe("var f\\u0030 = 103; f0", "103");
+
+// non-ASCII identifier letters as escape sequences
+shouldBe("var \\u00E9\\u0100\\u02AF\\u0388\\u18A8 = 104; \\u00E9\\u0100\\u02AF\\u0388\\u18A8;", "104");
+
+// invalid identifier characters as escape sequences
+shouldThrow("var f\\u00F7;");
+shouldThrow("var \\u0030;");
+shouldThrow("var test = { }; test.i= 0; test.i\\u002b= 1; test.i;");
+
+shouldBe("var test = { }; test.i= 0; test.i\u002b= 1; test.i;", "1");
 
 successfullyParsed = true