以下3段代码片段在RunJS中的执行结果:
代码片段1
<svg><script>alert(1);</script>
#弹窗成功
代码片段2
<script>alert(1);</script>
#弹窗失败
代码片段3
<svg><script>alert\u0028;1);</script>
#弹窗失败
1.代码片段1中,大概测试了下,只有在在<script>
标签前面添加<svg>
才能执行后面的js,而在不添加的情况下(如:代码片段2),则会执行失败。
根据片段1和片段2的综合结果,是否可以推测<svg>
标签对于后面的js代码的解码有影响。
比如:正式由于<svg>
标签的作用,所以浏览器才会将后面的代码<script>alert(1);</script>
首先进行html解码<script>alert(1);</script>
然后在对用js引擎执行其中的代码?
而在没有<svg>
标签的情况下,浏览器会直接执行<script>alert(1);</script>
2.对于代码片段3,为什么会执行失败呢?
因为,在js中,是可以使用Unicode字符的吧?
问题:针对以上的3种情况的执行结果进行分析比较
天蓬老师2017-04-10 14:47:39
原因在于Tokenization过程中的模式判断。
在HTML的tokenize过程中,对元素做了分类,不同的分类对应着不同的解析模式。<svg>
属于Foreign elements,而<script>
属于Raw text elements。之前在这个回答里解释过了。模式判断的过程可见WHATWG定义的标准。
script
属于Raw text elements,内部文本遵循着这样的规则:
<
不会根据实体字符来转义,(
不会根据实体字符来转义\u0028
不会被转义svg
在HTML的语境下,属于Foreign Elements,意味着标准不由HTML定义。而遵循着SVG的定义。
讲到这个首先要理解HTML、SVG、SGML和XML的继承关系:
如图所示,SVG直接继承自XML,它和XML一样,解析规则只区分两种情况:
<
被转义为<
,(
被转义为(
<![CDATA[
和]]>
包含的实体则不转义是的,SVG的标准里也定义了<script>
标签的存在。但它解析过程和HTML中定义的不一样,而是遵循SVG/XML的解析规则,不被<![CDATA[
和]]>
包含的实体一定会被转义。这就造成了楼主的用例差别。
还有\u0028
呢?
它只有在ECMAScript上下文的字符串、正则表达式、标志符中才被当作(
。见ECMAScript.
顺带一提,HTML5和HTML4、XHTML、SVG、SGML和XML均不太一样。不过楼主的用例里面RUNJS默认使用的是XHTML 1.0 Transitional的DTD,就没有这方面的混淆了。按下不表。