为什么在输入时Google Chrome控制台会抛出“SyntaxError: Unexpected token }”错误?

9
在谷歌浏览器的控制台中,当我们输入:
(

当我们输入 "(" 时,包括没有 "}" 在内,Chrome 报错为 "SyntaxError: Unexpected token }"。为什么会这样呢?
当我们输入以下内容时,也会得到相同的错误提示:
console.log(

没有 "}" !!!

下一个标记应该是参数列表或 ")",因此错误消息应该是 "Expected arguments list" 或 "Unclosed (" 或其他。

我想知道,控制台输入是否被解析为 StatementList(opt)(在ECMA-262中定义)?


能否贴出引发错误的代码? - Seth
1
@Seth:他确实做了,只是不容易看到。 - BoltClock
相关:https://dev59.com/52fWa4cB1Zd3GeqPgFm7 - Álvaro González
1个回答

22

编辑: 我找到了被评估的确切代码。 该代码在“src / third_party / WebKit / Source / WebCore / inspector / InjectedScriptSource.js”中。

在Chrome控制台评估您的代码之前,它会将其包装在with块中以将命令行函数带入作用域。 因此,您输入的实际上是在大括号内评估的。 意外的“}”标记是Chrome自动放置的标记。

Chrome传递给eval的代码为

with ((window && window.console && window.console._commandLineAPI) || {}) {
    <your code here>
};

以下示例适用于简单文本替换,结果是一个您可以展开以查看 answer 属性的对象:

} 0, { answer: 42

这个(重新格式化的)代码等效于:

with ((window && window.console && window.console._commandLineAPI) || {}) {
}
0, { answer: 42 };

}开头的符号用来结束with语句块。0,这一部分是必要的,它可以强制将对象文字解析为表达式而不是另一个块。然后,{ answer: 42是一个对象文本的开始,由插入的}符号来结束。

更有趣的是,这里提供了一些其他有效的输入(及其结果):

> }{ // an empty block, so no value
  undefined

> }!{ // !{} === false
  false

> }!!{ // !!{} === true
  true

> } +{ valueOf: function() { return 123; }
  123

1
+1 对于使用JavaScript进行巧妙的SQL注入来说是非常聪明的;-) 那个 0 确实很奇怪... - Cameron
感谢您的快速回复。嗯...这很棘手... Chrome 似乎解析 '{' + text + '}'。我尝试使用 }; '10 '+{,得到了 "10 [object Object]",这与 Firefox 的结果相同。 - itchyny
哇!太棒了!我看到InjectedScriptSource.js的第280行,确切地找到了你所说的东西!非常感谢! - itchyny
1
@Cameron:那就是JavaScript注入攻击了;-) - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接