Changeset 202828 in webkit
- Timestamp:
- Jul 5, 2016 1:05:02 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r202827 r202828 1 2016-07-05 Saam Barati <sbarati@apple.com> 2 3 our parsing for "use strict" is wrong when we first parse other directives that are not "use strict" but are located in a place where "use strict" would be valid 4 https://bugs.webkit.org/show_bug.cgi?id=159376 5 <rdar://problem/27108773> 6 7 Reviewed by Benjamin Poulain. 8 9 Our strict mode detection algorithm used to break if we ever saw a directive 10 that is not "use strict" but is syntactically located in a location where our 11 parser looks for "use strict". It broke as follows: 12 13 If a function started with a non "use strict" string literal, we will allow 14 "use strict" to be in any arbitrary statement inside the top level block in 15 the function body. For example, this meant that if we parsed a sequence of string 16 literals, followed by arbitrary statements, followed by "use strict", we would parse 17 the function as if it's in strict mode. This is the wrong behavior with respect to 18 the spec. This has consequences in other ways that break invariants of the language. 19 For example, we used to allow functions that are lexically nested inside what we deemed 20 a strict function to be non-strict. This used to fire an assertion if we ever skipped over 21 that function using the source provider cache, but it worked just fine in release builds. 22 23 This patch fixes this bug. 24 25 * parser/Parser.cpp: 26 (JSC::Parser<LexerType>::parseSourceElements): 27 (JSC::Parser<LexerType>::parseStatement): 28 * tests/stress/ensure-proper-strict-mode-parsing.js: Added. 29 (foo.bar): 30 (foo): 31 (bar.foo): 32 (bar): 33 (bar.call.undefined.this.throw.new.Error.string_appeared_here.baz): 34 (baz.call.undefined.undefined.throw.new.Error.string_appeared_here.jaz): 35 (jaz.call.undefined.this.throw.new.Error.string_appeared_here.vaz): 36 1 37 2016-07-05 Saam Barati <sbarati@apple.com> 2 38 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r202648 r202828 398 398 const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length 399 399 TreeSourceElements sourceElements = context.createSourceElements(); 400 bool seenNonDirective = false;401 400 const Identifier* directive = 0; 402 401 unsigned directiveLiteralLength = 0; 403 402 auto savePoint = createSavePoint(); 404 bool hasSetStrict = false;403 bool shouldCheckForUseStrict = mode == CheckForStrictMode; 405 404 406 405 while (TreeStatement statement = parseStatementListItem(context, directive, &directiveLiteralLength)) { 407 if ( mode == CheckForStrictMode && !seenNonDirective) {406 if (shouldCheckForUseStrict) { 408 407 if (directive) { 409 408 // "use strict" must be the exact literal without escape sequences or line continuation. 410 if ( !hasSetStrict &&directiveLiteralLength == lengthOfUseStrictLiteral && m_vm->propertyNames->useStrictIdentifier == *directive) {409 if (directiveLiteralLength == lengthOfUseStrictLiteral && m_vm->propertyNames->useStrictIdentifier == *directive) { 411 410 setStrictMode(); 412 hasSetStrict = true;411 shouldCheckForUseStrict = false; // We saw "use strict", there is no need to keep checking for it. 413 412 if (!isValidStrictMode()) { 414 413 if (m_parserState.lastFunctionName) { … … 429 428 continue; 430 429 } 431 } else 432 seenNonDirective = true; 430 431 // We saw a directive, but it wasn't "use strict". We reset our state to 432 // see if the next statement we parse is also a directive. 433 directive = nullptr; 434 } else { 435 // We saw a statement that wasn't in the form of a directive. The spec says that "use strict" 436 // is only allowed as the first statement, or after a sequence of directives before it, but 437 // not after non-directive statements. 438 shouldCheckForUseStrict = false; 439 } 433 440 } 434 441 context.appendStatement(sourceElements, statement); … … 1602 1609 DepthManager statementDepth(&m_statementDepth); 1603 1610 m_statementDepth++; 1604 directive = 0;1605 1611 int nonTrivialExpressionCount = 0; 1606 1612 failIfStackOverflow(); … … 1721 1727 TreeStatement exprStatement = parseExpressionStatement(context); 1722 1728 if (directive && nonTrivialExpressionCount != m_parserState.nonTrivialExpressionCount) 1723 directive = 0;1729 directive = nullptr; 1724 1730 result = exprStatement; 1725 1731 break;
Note: See TracChangeset
for help on using the changeset viewer.