mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Bug 601262 - A string literal containing an octal escape before a strict mode directive should be a syntax error. (Yes, this requirement is ugly, but it's what ES5 says.) r=brendan
--HG-- extra : rebase_source : c30be5f90e4b069da4ea6f035598f9a3262fa8e0
This commit is contained in:
parent
bf3493284e
commit
5997a2fb7a
@ -865,6 +865,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
|
||||
#endif
|
||||
|
||||
inDirectivePrologue = true;
|
||||
tokenStream.setOctalCharacterEscape(false);
|
||||
for (;;) {
|
||||
tt = tokenStream.peekToken(TSF_OPERAND);
|
||||
if (tt <= TOK_EOF) {
|
||||
@ -879,8 +880,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
|
||||
goto out;
|
||||
JS_ASSERT(!cg.blockNode);
|
||||
|
||||
if (inDirectivePrologue)
|
||||
inDirectivePrologue = parser.recognizeDirectivePrologue(pn);
|
||||
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
|
||||
goto out;
|
||||
|
||||
if (!js_FoldConstants(cx, pn, &cg))
|
||||
goto out;
|
||||
@ -3225,13 +3226,33 @@ Parser::functionExpr()
|
||||
* if it can't possibly be a directive, now or in the future.
|
||||
*/
|
||||
bool
|
||||
Parser::recognizeDirectivePrologue(JSParseNode *pn)
|
||||
Parser::recognizeDirectivePrologue(JSParseNode *pn, bool *isDirectivePrologueMember)
|
||||
{
|
||||
if (!pn->isDirectivePrologueMember())
|
||||
return false;
|
||||
*isDirectivePrologueMember = pn->isDirectivePrologueMember();
|
||||
if (!*isDirectivePrologueMember)
|
||||
return true;
|
||||
if (pn->isDirective()) {
|
||||
JSAtom *directive = pn->pn_kid->pn_atom;
|
||||
if (directive == context->runtime->atomState.useStrictAtom) {
|
||||
/*
|
||||
* Unfortunately, Directive Prologue members in general may contain
|
||||
* escapes, even while "use strict" directives may not. Therefore
|
||||
* we must check whether an octal character escape has been seen in
|
||||
* any previous directives whenever we encounter a "use strict"
|
||||
* directive, so that the octal escape is properly treated as a
|
||||
* syntax error. An example of this case:
|
||||
*
|
||||
* function error()
|
||||
* {
|
||||
* "\145"; // octal escape
|
||||
* "use strict"; // retroactively makes "\145" a syntax error
|
||||
* }
|
||||
*/
|
||||
if (tokenStream.hasOctalCharacterEscape()) {
|
||||
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_DEPRECATED_OCTAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
tc->flags |= TCF_STRICT_MODE_CODE;
|
||||
tokenStream.setStrictMode();
|
||||
}
|
||||
@ -3249,7 +3270,6 @@ Parser::statements()
|
||||
{
|
||||
JSParseNode *pn, *pn2, *saveBlock;
|
||||
TokenKind tt;
|
||||
bool inDirectivePrologue = tc->atTopLevel();
|
||||
|
||||
JS_CHECK_RECURSION(context, return NULL);
|
||||
|
||||
@ -3262,6 +3282,8 @@ Parser::statements()
|
||||
saveBlock = tc->blockNode;
|
||||
tc->blockNode = pn;
|
||||
|
||||
bool inDirectivePrologue = tc->atTopLevel();
|
||||
tokenStream.setOctalCharacterEscape(false);
|
||||
for (;;) {
|
||||
tt = tokenStream.peekToken(TSF_OPERAND);
|
||||
if (tt <= TOK_EOF || tt == TOK_RC) {
|
||||
@ -3279,8 +3301,8 @@ Parser::statements()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (inDirectivePrologue)
|
||||
inDirectivePrologue = recognizeDirectivePrologue(pn2);
|
||||
if (inDirectivePrologue && !recognizeDirectivePrologue(pn2, &inDirectivePrologue))
|
||||
return NULL;
|
||||
|
||||
if (pn2->pn_type == TOK_FUNCTION) {
|
||||
/*
|
||||
|
@ -1118,7 +1118,7 @@ private:
|
||||
/*
|
||||
* Additional JS parsers.
|
||||
*/
|
||||
bool recognizeDirectivePrologue(JSParseNode *pn);
|
||||
bool recognizeDirectivePrologue(JSParseNode *pn, bool *isDirectivePrologueMember);
|
||||
|
||||
enum FunctionType { GETTER, SETTER, GENERAL };
|
||||
bool functionArguments(JSTreeContext &funtc, JSFunctionBox *funbox, JSFunction *fun,
|
||||
|
@ -1192,6 +1192,7 @@ TokenStream::getTokenInternal()
|
||||
JSMSG_DEPRECATED_OCTAL)) {
|
||||
goto error;
|
||||
}
|
||||
setOctalCharacterEscape();
|
||||
}
|
||||
if ('0' <= c && c < '8') {
|
||||
val = 8 * val + JS7_UNDEC(c);
|
||||
|
@ -263,6 +263,7 @@ enum TokenStreamFlags
|
||||
TSF_XMLTAGMODE = 0x200, /* scanning within an XML tag in E4X */
|
||||
TSF_XMLTEXTMODE = 0x400, /* scanning XMLText terminal from E4X */
|
||||
TSF_XMLONLYMODE = 0x800, /* don't scan {expr} within text/tag */
|
||||
TSF_OCTAL_CHAR = 0x1000, /* observed a octal character escape */
|
||||
|
||||
/*
|
||||
* To handle the hard case of contiguous HTML comments, we want to clear the
|
||||
@ -333,12 +334,15 @@ class TokenStream
|
||||
void setXMLTagMode(bool enabled = true) { setFlag(enabled, TSF_XMLTAGMODE); }
|
||||
void setXMLOnlyMode(bool enabled = true) { setFlag(enabled, TSF_XMLONLYMODE); }
|
||||
void setUnexpectedEOF(bool enabled = true) { setFlag(enabled, TSF_UNEXPECTED_EOF); }
|
||||
void setOctalCharacterEscape(bool enabled = true) { setFlag(enabled, TSF_OCTAL_CHAR); }
|
||||
|
||||
bool isStrictMode() { return !!(flags & TSF_STRICT_MODE_CODE); }
|
||||
bool isXMLTagMode() { return !!(flags & TSF_XMLTAGMODE); }
|
||||
bool isXMLOnlyMode() { return !!(flags & TSF_XMLONLYMODE); }
|
||||
bool isUnexpectedEOF() { return !!(flags & TSF_UNEXPECTED_EOF); }
|
||||
bool isEOF() const { return !!(flags & TSF_EOF); }
|
||||
bool isError() const { return !!(flags & TSF_ERROR); }
|
||||
bool hasOctalCharacterEscape() const { return flags & TSF_OCTAL_CHAR; }
|
||||
|
||||
/* Mutators. */
|
||||
bool reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN errorNumber, va_list ap);
|
||||
|
78
js/src/tests/ecma_5/strict/directive-prologue-01.js
Normal file
78
js/src/tests/ecma_5/strict/directive-prologue-01.js
Normal file
@ -0,0 +1,78 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 601262;
|
||||
var summary =
|
||||
"A string literal containing an octal escape before a strict mode " +
|
||||
"directive should be a syntax error";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
try
|
||||
{
|
||||
eval(" '\\145'; 'use strict'; ");
|
||||
throw new Error("no error thrown for eval");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(e instanceof SyntaxError, true,
|
||||
"wrong error for octal-escape before strict directive in eval");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Function(" '\\145'; 'use strict'; ");
|
||||
throw new Error("no error thrown for Function");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(e instanceof SyntaxError, true,
|
||||
"wrong error for octal-escape before strict directive in Function");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
eval(" function f(){ '\\145'; 'use strict'; } ");
|
||||
throw new Error("no error thrown for eval of function");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(e instanceof SyntaxError, true,
|
||||
"wrong error for octal-escape before strict directive in eval of " +
|
||||
"function");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Function(" function f(){ '\\145'; 'use strict'; } ");
|
||||
throw new Error("no error thrown for eval of function");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(e instanceof SyntaxError, true,
|
||||
"wrong error for octal-escape before strict directive in eval of " +
|
||||
"function");
|
||||
}
|
||||
|
||||
eval("function notAnError1() { 5; '\\145'; function g() { 'use strict'; } }");
|
||||
|
||||
Function("function notAnError2() { 5; '\\145'; function g() { 'use strict'; } }");
|
||||
|
||||
function notAnError3()
|
||||
{
|
||||
5;
|
||||
"\145";
|
||||
function g() { "use strict"; }
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("All tests passed!");
|
@ -37,3 +37,4 @@ script regress-532254.js
|
||||
script regress-532041.js
|
||||
script unbrand-this.js
|
||||
script this-for-function-expression-recursion.js
|
||||
script directive-prologue-01.js
|
||||
|
Loading…
Reference in New Issue
Block a user