Permalink
Browse files

Flag more E4x and treat scripts right (bug 820460)

  • Loading branch information...
1 parent 163ce74 commit 0aba641a25bd0fc99e671cc5d00d5112110ccc11 @mattbasta mattbasta committed Feb 5, 2013
@@ -45,4 +45,4 @@ def test_warn_e4x(self):
var x = <foo></foo>;
""")
self.assert_failed(with_warnings=True)
- self.assert_compat_warning("warning")
+ self.assert_compat_error("warning")
View
@@ -8,15 +8,14 @@ class TestE4X(TestCase):
"""
def run_script(self, script):
- super(TestE4X, self).run_script(script)
- self.err.warnings = filter(lambda w:
- not w["id"][-1].startswith("warn_e4x"),
- self.err.warnings)
+ output = super(TestE4X, self).run_script(script)
+ self.err.warnings = filter(
+ lambda w: w["id"][-1] == "e4x", self.err.warnings)
+ return output
def test_pass(self):
"""Test that E4X isn't immediately rejected."""
self.run_script("""var x = <foo a={x}><bar /><{zap} /></foo>;""")
- self.assert_silent()
def test_default_declaration(self):
"""
@@ -56,15 +55,15 @@ def test_xmlname_string(self):
<errors/>
</report>;
""")
- self.assert_silent()
+ self.assert_failed(with_warnings=True)
def test_xmlattributeselector(self):
"""Test that XMLAttributeSelectors don't throw tracebacks."""
self.run_script("""
var x = <foo zip="zap"><bar /></foo>;
var y = x.@zip;
""")
- self.assert_silent()
+ self.assert_failed(with_warnings=True)
def test_double_colon(self):
"""
@@ -76,5 +75,21 @@ def test_double_colon(self):
xmlns:nsTypes={nsTypes}/>;
req::asdf.oijaewr::aasdf = "foo";
""")
- self.assert_silent()
+ self.assert_failed(with_warnings=True)
+
+ def test_all_deprecated(self):
+ """Test that all of the node types are flagged."""
+ def wrap(line):
+ print line
+ self.setUp()
+ self.run_script(line)
+ self.assert_failed(with_warnings=True)
+ yield wrap, 'var x = <![CDATA[Foo.]]>;'
+ yield wrap, 'var x = <>Bar.</>;'
+ yield wrap, 'var x = XML("<foo/>");'
+ yield wrap, 'var x = QName("thing", "stuff");'
+ yield wrap, 'var x = Namespace("foo", "bar");'
+ yield wrap, 'var x = frag..foo;'
+ yield wrap, 'var x = thing.@foo;'
+ yield wrap, 'var x = thing.ns::thing;'
@@ -99,7 +99,7 @@ def test_cdata_properly():
# Test that there are no problems if the CDATA element starts or ends on
# the same line as the parent tag.
err = _test_xul_raw("""<foo>
- <script><![CDATA[
+ <script type="text/x-jquery-tmpl"><![CDATA[
<button><p><span><foo>
</bar></zap>
<selfclosing />
@@ -133,6 +133,41 @@ def test_cdata_properly():
]]>""", "foo.xul", should_fail=False)
+def test_non_js_not_executed():
+ err = _test_xul_raw("""<foo>
+ <script type="text/x-jquery-tmpl">
+ <![CDATA[
+ <button><p><span><foo>
+ </bar></zap>
+ <selfclosing />
+ <><><><""><!><
+ ]]>
+ </script>
+ </foo>""", "foo.xul", should_fail=False)
+
+ err = _test_xul_raw("""<foo>
+ <script type="application/javascript">
+ <![CDATA[
+ <button><p><span><foo>
+ </bar></zap>
+ <selfclosing />
+ <><><><""><!><
+ ]]>
+ </script>
+ </foo>""", "foo.xul", should_fail=True)
+
+ err = _test_xul_raw("""<foo>
+ <script>
+ <![CDATA[
+ <button><p><span><foo>
+ </bar></zap>
+ <selfclosing />
+ <><><><""><!><
+ ]]>
+ </script>
+ </foo>""", "foo.xul", should_fail=True)
+
+
def test_xml_overclosing():
"Tests an XML file that has overclosed elements"
_test_xul("tests/resources/markup/markuptester/overclose.xml", True)
@@ -780,6 +780,9 @@ def _expr_binary(traverser, node):
right = traverser._traverse_node(node["right"])
traverser._debug("Is dirty? %r" % right.dirty, 1)
+ if operator == "..":
+ traverser.warn_e4x()
+
traverser.debug_level -= 1
# Dirty l or r values mean we can skip the expression. A dirty value
@@ -61,6 +61,11 @@ def wrap(traverser):
message=JAVA_MESSAGE, bug=748343)
+@register_entity("XML")
+def XML(traverser):
+ return {"dangerous": traverser.warn_e4x}
+
+
@register_entity("document.write")
def document_write(traverser):
def on_write(wrapper, arguments, traverser):
@@ -114,8 +114,9 @@ def node(branches=None, dynamic=False, action=None, returns=False,
}
-E4X_NODES = set(["XMLElement", "XMLList", "XMLStartTag", "XMLEndTag",
- "XMLPointTag", "XMLName", "XMLEscape",
- "XMLDefaultDeclaration", "XMLQualifiedIdentifier",
- "XMLFunctionQualifiedIdentifier",
- "XMLAttributeSelector", "XMLFilterExpression"])
+E4X_NODES = set([
+ "XMLElement", "XMLList", "XMLStartTag", "XMLEndTag", "XMLPointTag",
+ "XMLName", "XMLEscape", "XMLDefaultDeclaration",
+ "XMLQualifiedIdentifier", "XMLFunctionQualifiedIdentifier",
+ "XMLAttributeSelector", "XMLFilterExpression", "XMLAnyName", "XML",
+ "XMLCdata", "XMLComment", "XMLProcessingInstruction"])
@@ -493,6 +493,9 @@ def build_quick_xpcom(method, interface, traverser):
u"RegExp": {"value": {u"prototype": {"readonly": True}}},
u"Date": {"value": {u"prototype": {"readonly": True}}},
u"File": {"value": {u"prototype": {"readonly": True}}},
+ u"XML": entity("XML"),
+ u"QName": entity("XML"),
+ u"Namespace": entity("XML"),
u"Math":
{"value":
@@ -117,8 +117,6 @@ def run(self, data):
filename=self.filename)
def _traverse_node(self, node):
- "Finds a node's internal blocks and helps manage state."
-
if node is None:
return JSWrapper(JSObject(), traverser=self, dirty=True)
@@ -128,46 +126,20 @@ def _traverse_node(self, node):
if isinstance(node, types.StringTypes):
return JSWrapper(JSLiteral(node), traverser=self)
- elif "type" not in node or node["type"] not in DEFINITIONS:
- return JSWrapper(JSObject(), traverser=self, dirty=True)
-
- self._debug("TRAVERSE>>%s" % node["type"])
- self.debug_level += 1
# Extract location information if it's available
if "loc" in node and node["loc"] is not None:
self.line = self.start_line + int(node["loc"]["start"]["line"])
self.position = int(node["loc"]["start"]["column"])
- if node["type"] in E4X_NODES and not self.warned_e4x:
- self.warned_e4x = True
+ if node.get("type") in E4X_NODES and not self.warned_e4x:
+ self.warn_e4x()
- if self.err.supports_version(FX15_DEFINITION):
- self.err.warning(
- ("js", "traverser", "warn_e4x_compat"),
- "E4X Deprecated",
- "It is no longer possible to pass E4X objects between most "
- "contexts, including different chrome windows or JS "
- "modules. You should also be aware that E4X is in a quick "
- "deprecation path. See %s for more information." %
- "https://developer.mozilla.org/en-US/docs/E4X",
- filename=self.filename,
- line=self.line,
- column=self.position,
- context=self.context,
- compatibility_type="warning",
- for_appversions=FX15_DEFINITION,
- tier=5)
- else:
- self.err.warning(
- ("js", "traverser", "warn_e4x"),
- "E4X Deprecated",
- "E4X has been deprecated and will be disabled by default "
- "for content in Gecko 16, and will be removed in Gecko 17.",
- filename=self.filename,
- line=self.line,
- column=self.position,
- context=self.context)
+ if node.get("type") not in DEFINITIONS:
+ return JSWrapper(JSObject(), traverser=self, dirty=True)
+
+ self._debug("TRAVERSE>>%s" % node["type"])
+ self.debug_level += 1
# Extract properties about the node that we're traversing
(branches, establish_context, action, returns,
@@ -201,13 +173,11 @@ def _traverse_node(self, node):
for branch in branches:
if branch in node:
self._debug("BRANCH>>%s" % branch)
- self.debug_level += 1
b = node[branch]
if isinstance(b, list):
map(self._traverse_node, b)
else:
self._traverse_node(b)
- self.debug_level -= 1
self.debug_level -= 1
# If we defined a context, pop it.
@@ -231,6 +201,26 @@ def _traverse_node(self, node):
node["__traversal"] = None
return JSWrapper(JSObject(), traverser=self, dirty=True)
+ def warn_e4x(self, *args, **kwargs):
+ if self.warned_e4x:
+ return
+ self.warned_e4x = True
+
+ self.err.warning(
+ err_id=("js", "traverser", "e4x"),
+ warning="E4X Deprecated/Removed",
+ description="It is no longer possible to pass E4X objects "
+ "between most contexts, including different chrome "
+ "windows or JS modules. E4X will be completely "
+ "removed by Gecko 20 (or possibly earlier). See %s "
+ "for more information." %
+ "https://developer.mozilla.org/en-US/docs/E4X",
+ filename=self.filename,
+ line=self.line,
+ column=self.position,
+ context=self.context,
+ compatibility_type="error")
+
def _push_block_context(self):
"Adds a block context to the current interpretation frame"
self.contexts.append(JSContext("block"))
@@ -56,6 +56,8 @@ def __init__(self, err, strict=True, debug=False):
self.xml_buffer = []
self.xbl = False
+ self.xml_state_scripts = []
+
self.reported = set()
self.found_scripts = set() # A set of script URLs in the doc.
@@ -95,7 +97,7 @@ def process(self, filename, data, extension="xul"):
if cdatapos:
self._feed_parser(search_line[:cdatapos])
# Collect the rest of the line to send it to the buffer.
- search_line = search_line[cdatapos:]
+ search_line = search_line[cdatapos + 9:]
buffering = True
continue
@@ -155,16 +157,14 @@ def _feed_parser(self, line):
return
if self.strict:
- self.err.warning(("markup",
- "_feed",
- "parse_error"),
- "Markup parsing error",
- ["There was an error parsing a markup "
- "file.",
- str(inst)],
- self.filename,
- line=self.line,
- context=self.context)
+ self.err.warning(
+ err_id=("markup", "_feed", "parse_error"),
+ warning="Markup parsing error",
+ description=["There was an error parsing a markup "
+ "file.", str(inst)],
+ filename=self.filename,
+ line=self.line,
+ context=self.context)
self.reported.add("markup")
def handle_startendtag(self, tag, attrs):
@@ -450,6 +450,10 @@ def handle_starttag(self, tag, attrs, self_closing=False):
line=self.line,
context=self.context)
+ if tag == "script":
+ self.xml_state_scripts.append(any(
+ (x[0] == "type" and "javascript" not in x[1]) for x in attrs))
+
# When the dev forgets their <!-- --> on a script tag, bad
# things happen.
if "script" in self.xml_state and tag != "script":
@@ -520,6 +524,9 @@ def handle_endtag(self, tag):
data_buffer = self.xml_buffer.pop()
old_state = self.xml_state.pop()
old_line = self.xml_line_stack.pop()
+ script_type = True
+ if old_state == "script":
+ script_type = self.xml_state_scripts.pop()
# If the tag on the stack isn't what's being closed and it also
# classifies as a self-closing tag, we just recursively close
@@ -553,7 +560,7 @@ def handle_endtag(self, tag):
# Perform analysis on collected data.
if data_buffer:
- if tag == "script":
+ if tag == "script" and not script_type:
scripting.test_js_snippet(err=self.err, data=data_buffer,
filename=self.filename,
line=old_line, context=self.context)

0 comments on commit 0aba641

Please sign in to comment.