Made the regex tests universal (bug 669188)

This commit is contained in:
Matt Basta 2011-07-18 15:31:58 -07:00
Родитель 93dc9cd379
Коммит 55aa902574
8 изменённых файлов: 183 добавлений и 184 удалений

Просмотреть файл

@ -1,6 +1,8 @@
from nose.tools import eq_
from helper import MockXPI
from validator.errorbundler import ErrorBundle
import validator.testcases.content
import validator.testcases.scripting
validator.testcases.scripting.traverser.DEBUG = True
@ -12,11 +14,12 @@ def _do_test(path):
return _do_test_raw(script, path)
def _do_test_raw(script, path="foo", bootstrap=False, ignore_pollution=True,
def _do_test_raw(script, path="foo.js", bootstrap=False, ignore_pollution=True,
detected_type=None):
"Performs a test on a JS file"
err = validator.testcases.scripting.traverser.MockBundler()
err.supported_versions = {}
if bootstrap:
err.save_resource("em:bootstrap", True)
if detected_type:
@ -24,7 +27,7 @@ def _do_test_raw(script, path="foo", bootstrap=False, ignore_pollution=True,
if ignore_pollution:
validator.testcases.scripting.traverser.IGNORE_POLLUTION = True
validator.testcases.scripting.test_js_file(err, path, script)
validator.testcases.content._process_file(err, MockXPI(), path, script)
validator.testcases.scripting.traverser.IGNORE_POLLUTION = False
if err.final_context is not None:
print err.final_context.output()
@ -32,7 +35,7 @@ def _do_test_raw(script, path="foo", bootstrap=False, ignore_pollution=True,
return err
def _do_real_test_raw(script, path="foo", versions=None, detected_type=None,
def _do_real_test_raw(script, path="foo.js", versions=None, detected_type=None,
metadata=None, resources=None):
"""Perform a JS test using a non-mock bundler."""
@ -45,7 +48,7 @@ def _do_real_test_raw(script, path="foo", versions=None, detected_type=None,
if resources is not None:
err.resources = resources
validator.testcases.scripting.test_js_file(err, path, script, line=30)
validator.testcases.content._process_file(err, MockXPI(), path, script)
return err

Просмотреть файл

@ -32,12 +32,9 @@ def test_navigator_language():
"""
Test that 'navigator.language' is flagged as potentially incompatile with FX5.
"""
err = ErrorBundle()
err.supported_versions = {}
flagged = "alert(navigator.language);"
scripting.test_js_snippet(err, flagged, "foo")
err = _do_real_test_raw(flagged)
assert not err.failed()
assert not any(err.compat_summary[k] for k in err.compat_summary)

Просмотреть файл

@ -130,13 +130,11 @@ def test_jar_nonsubpackage():
def test_markup():
"Tests markup files in the content validator."
err = ErrorBundle(None, True)
mock_package = MockXPI(
{"foo.xml":
"tests/resources/content/junk.xpi"})
err = ErrorBundle()
err.supported_versions = {}
mock_package = MockXPI({"foo.xml": "tests/resources/content/junk.xpi"})
content.testendpoint_markup = \
MockMarkupEndpoint(("process", ))
content.testendpoint_markup = MockMarkupEndpoint(("process", ))
result = content.test_packed_packages(
err,
@ -155,44 +153,34 @@ def test_css():
"Tests css files in the content validator."
err = ErrorBundle()
mock_package = MockXPI(
{"foo.css":
"tests/resources/content/junk.xpi"})
err.supported_versions = {}
mock_package = MockXPI({"foo.css": "tests/resources/content/junk.xpi"})
content.testendpoint_css = \
MockTestEndpoint(("test_css_file", ))
content.testendpoint_css = MockTestEndpoint(("test_css_file", ))
result = content.test_packed_packages(
err,
mock_package)
result = content.test_packed_packages(err, mock_package)
print result
assert result == 1
content.testendpoint_css.assert_expectation(
"test_css_file",
1)
content.testendpoint_css.assert_expectation(
"test_css_file",
0,
"subpackage")
content.testendpoint_css.assert_expectation("test_css_file", 1)
content.testendpoint_css.assert_expectation("test_css_file", 0,
"subpackage")
def test_hidden_files():
"""Tests that hidden files are reported."""
err = ErrorBundle()
mock_package = MockXPI({".hidden":
"tests/resources/content/junk.xpi"})
err.supported_versions = {}
mock_package = MockXPI({".hidden": "tests/resources/content/junk.xpi"})
content.test_packed_packages(err,
mock_package)
content.test_packed_packages(err, mock_package)
print err.print_summary(verbose=True)
assert err.failed()
err = ErrorBundle()
mock_package_mac = MockXPI({"dir/__MACOSX/foo":
"tests/resources/content/junk.xpi"})
content.test_packed_packages(err,
mock_package_mac)
content.test_packed_packages(err, mock_package_mac)
print err.print_summary(verbose=True)
assert err.failed()
@ -219,49 +207,40 @@ def test_password_in_defaults_prefs():
def test_langpack():
"Tests a language pack in the content validator."
err = ErrorBundle(None, True)
err = ErrorBundle()
err.supported_versions = {}
err.set_type(PACKAGE_LANGPACK)
mock_package = MockXPI(
{"foo.dtd":
"tests/resources/content/junk.xpi"})
mock_package = MockXPI({"foo.dtd": "tests/resources/content/junk.xpi"})
content.testendpoint_langpack = \
MockTestEndpoint(("test_unsafe_html", ))
content.testendpoint_langpack = MockTestEndpoint(("test_unsafe_html", ))
result = content.test_packed_packages(
err,
mock_package)
result = content.test_packed_packages(err, mock_package)
print result
assert result == 1
content.testendpoint_langpack.assert_expectation(
"test_unsafe_html",
1)
content.testendpoint_langpack.assert_expectation(
"test_unsafe_html",
0,
"subpackage")
content.testendpoint_langpack.assert_expectation("test_unsafe_html", 1)
content.testendpoint_langpack.assert_expectation("test_unsafe_html", 0,
"subpackage")
def test_jar_subpackage_bad():
"Tests JAR files that are bad subpackages."
err = ErrorBundle(None, True)
err = ErrorBundle()
mock_package = MockXPI({"chrome/subpackage.jar":
"tests/resources/content/junk.xpi"})
content.testendpoint_validator = \
MockTestEndpoint(("test_inner_package", ))
content.testendpoint_validator = MockTestEndpoint(("test_inner_package", ))
result = content.test_packed_packages(
err,
mock_package)
result = content.test_packed_packages(err, mock_package)
print result
assert err.failed()
class MockTestEndpoint(object):
"""Simulates a test module and reports whether individual tests
have been attempted on it."""
"""
Simulates a test module and reports whether individual tests have been
attempted on it.
"""
def __init__(self, expected, td_error=False):
expectations = {}

Просмотреть файл

@ -1,10 +1,13 @@
from helper import MockXPI
from js_helper import _do_real_test_raw as _do_test_raw
from validator.decorator import versions_after
from js_helper import _do_test_raw, _do_real_test_raw
from validator.errorbundler import ErrorBundle
import validator.testcases.content
import validator.testcases.regex as regex_tests
def test_valid():
"Tests a valid string in a JS bit"
assert not _do_test_raw("var x = 'network.foo';").failed()
@ -16,6 +19,16 @@ def test_basic_regex_fail():
assert _do_test_raw("var x = 'network.websocket.foobar';").failed()
assert _do_test_raw("var x = 'browser.preferences.instantApply';").failed()
err = ErrorBundle()
err.supported_versions = {}
result = validator.testcases.content._process_file(
err, MockXPI(), "foo.xml",
"""
All I wanna do is browser.preferences.instantApply() to you
""")
assert result
assert err.failed()
def test_js_category_regex_fail():
"Tests that JS category registration causes a warning"
@ -39,8 +52,9 @@ def test_bug_548645():
var x = foo.newThread;
var w = foo["newThread"];
""")
print results.message_count
assert results.message_count == 3
print results.print_summary(verbose=True)
assert ((len(results.errors) + len(results.warnings) +
len(results.notices)) == 3)
def test_bug_652575():
@ -51,13 +65,13 @@ def test_bug_652575():
def test_app_update_timer():
"""Flag instances of app.update.timer in compatibility."""
err = _do_real_test_raw("""
err = _do_test_raw("""
var f = app.update.timer;
""")
assert not err.failed()
assert not any(err.compat_summary.values())
err = _do_real_test_raw("""
err = _do_test_raw("""
var f = app.update.timer;
""", versions={"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}":
versions_after("firefox", "6.0a1")})
@ -68,27 +82,27 @@ def test_app_update_timer():
def test_incompatible_uris():
"""Flag instances of javascript:/data: in compatibility."""
err = _do_real_test_raw("""
err = _do_test_raw("""
var f = "javascript:foo();";
""")
assert not err.failed()
assert not any(err.compat_summary.values())
err = _do_real_test_raw("""
err = _do_test_raw("""
var f = "javascript:foo();";
""", versions={"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}":
versions_after("firefox", "6.0a1")})
assert not err.failed()
assert err.compat_summary["warnings"]
err = _do_real_test_raw("""
err = _do_test_raw("""
var f = "data:foo();";
""", versions={"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}":
versions_after("firefox", "6.0a1")})
assert not err.failed()
assert err.compat_summary["warnings"]
err = _do_real_test_raw("""
err = _do_test_raw("""
var foo = "postdata:LOL NOT THE CASE";
""", versions={"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}":
versions_after("firefox", "6.0a1")})

Просмотреть файл

@ -32,5 +32,4 @@ def test_js_banned():
err = _do_real_test_raw("""foo();""", detected_type=PACKAGE_THEME)
print err.print_summary(verbose=True)
assert err.failed()
assert all(e["line"] for e in err.warnings)

Просмотреть файл

@ -3,6 +3,7 @@ import hashlib
import re
from StringIO import StringIO
from regex import run_regex_tests
from validator.contextgenerator import ContextGenerator
from validator import decorator
from validator import submain as testendpoint_validator
@ -17,6 +18,7 @@ from validator.textfilter import is_standard_ascii
PASSWORD_REGEX = re.compile("password", re.I)
OSX_REGEX = re.compile("__MACOSX")
@decorator.register_test(tier=1)
def test_xpcnativewrappers(err, xpi_package=None):
@ -57,13 +59,9 @@ def test_packed_packages(err, xpi_package=None):
"whitelist_hashes.txt")) as f:
hash_whitelist = [x[:-1] for x in f]
macosx_regex = re.compile("__MACOSX")
# Iterate each item in the package.
for name in xpi_package:
name_lower = name.lower()
if (macosx_regex.search(name) or
if (OSX_REGEX.search(name) or
name.startswith(".") or
name.split("/")[-1].startswith(".")):
err.warning(
@ -101,116 +99,123 @@ def test_packed_packages(err, xpi_package=None):
name)
continue
processed = False
# If that item is a container file, unzip it and scan it.
if name_lower.endswith(".jar"):
# This is either a subpackage or a nested theme.
# Process the file.
processed = _process_file(err, xpi_package, name, file_data)
if processed is None:
continue
is_subpackage = not err.get_resource("is_multipackage")
# Unpack the package and load it up.
package = StringIO(file_data)
try:
sub_xpi = XPIManager(package, mode="r", name=name,
subpackage=is_subpackage)
except:
err.error(("testcases_content",
"test_packed_packages",
"jar_subpackage_corrupt"),
"Subpackage corrupt.",
"The subpackage could not be opened due to issues "
"with corruption. Ensure that the file is valid.",
name)
continue
# Let the error bunder know we're in a sub-package.
err.push_state(name.lower())
err.set_type(PACKAGE_SUBPACKAGE if
is_subpackage else
PACKAGE_THEME)
err.set_tier(1)
supported_versions = err.supported_versions
if is_subpackage:
testendpoint_validator.test_inner_package(err, sub_xpi)
else:
testendpoint_validator.test_package(err, package, name)
package.close()
err.pop_state()
err.set_tier(2)
err.supported_versions = supported_versions
elif name_lower.endswith(".xpi"):
# It's not a subpackage, it's a nested extension. These are
# found in multi-extension packages.
# Unpack!
package = StringIO(file_data)
err.push_state(name_lower)
err.set_tier(1)
# There are no expected types for packages within a multi-
# item package.
testendpoint_validator.test_package(err, package, name)
package.close()
err.pop_state()
err.set_tier(2) # Reset to the current tier
elif name_lower.endswith((".xul", ".xml", ".html", ".xhtml", ".xbl")):
parser = testendpoint_markup.MarkupParser(err)
parser.process(name,
file_data,
xpi_package.info(name)["extension"])
processed = True
elif name_lower.endswith((".css", ".js", ".jsm")):
if not file_data:
continue
# Convert the file data to unicode
file_data = unicodehelper.decode(file_data)
if name_lower.endswith(".css"):
testendpoint_css.test_css_file(err,
name,
file_data)
elif name_lower.endswith((".js", ".jsm")):
# Test for "password" in defaults/preferences files; bug 647109
if fnmatch.fnmatch(name, "defaults/preferences/*.js"):
match = PASSWORD_REGEX.search(file_data)
if match:
context = ContextGenerator(file_data)
err.warning(
err_id=("testcases_content",
"test_packed_packages",
"password_in_js"),
warning="Passwords may be stored in defaults/"
"preferences JS files",
description="Storing passwords in the preferences "
"is insecure and the Login Manager "
"should be used instead.",
filename=name,
line=context.get_line(match.start()),
context=context)
testendpoint_js.test_js_file(err,
name,
file_data)
# This is tested in test_langpack.py
if err.detected_type == PACKAGE_LANGPACK and not processed:
testendpoint_langpack.test_unsafe_html(err,
name,
file_data)
testendpoint_langpack.test_unsafe_html(err, name, file_data)
# This aids in creating unit tests.
processed_files += 1
return processed_files
def _process_file(err, xpi_package, name, file_data):
"""Process a single file's content tests."""
name_lower = name.lower()
# If that item is a container file, unzip it and scan it.
if name_lower.endswith(".jar"):
# This is either a subpackage or a nested theme.
is_subpackage = not err.get_resource("is_multipackage")
# Unpack the package and load it up.
package = StringIO(file_data)
try:
sub_xpi = XPIManager(package, mode="r", name=name,
subpackage=is_subpackage)
except:
err.error(("testcases_content",
"test_packed_packages",
"jar_subpackage_corrupt"),
"Subpackage corrupt.",
"The subpackage could not be opened due to issues "
"with corruption. Ensure that the file is valid.",
name)
return None
# Let the error bunder know we're in a sub-package.
err.push_state(name.lower())
err.set_type(PACKAGE_SUBPACKAGE if
is_subpackage else
PACKAGE_THEME)
err.set_tier(1)
supported_versions = err.supported_versions
if is_subpackage:
testendpoint_validator.test_inner_package(err, sub_xpi)
else:
testendpoint_validator.test_package(err, package, name)
package.close()
err.pop_state()
err.set_tier(2)
err.supported_versions = supported_versions
elif name_lower.endswith(".xpi"):
# It's not a subpackage, it's a nested extension. These are
# found in multi-extension packages.
# Unpack!
package = StringIO(file_data)
err.push_state(name_lower)
err.set_tier(1)
# There are no expected types for packages within a multi-
# item package.
testendpoint_validator.test_package(err, package, name)
package.close()
err.pop_state()
err.set_tier(2) # Reset to the current tier
elif name_lower.endswith((".xul", ".xml", ".html", ".xhtml", ".xbl")):
parser = testendpoint_markup.MarkupParser(err)
parser.process(name, file_data,
xpi_package.info(name)["extension"])
run_regex_tests(file_data, err, name)
return True
elif name_lower.endswith((".css", ".js", ".jsm")):
if not file_data:
return None
# Convert the file data to unicode
file_data = unicodehelper.decode(file_data)
if name_lower.endswith(".css"):
testendpoint_css.test_css_file(err, name, file_data)
elif name_lower.endswith((".js", ".jsm")):
# Test for "password" in defaults/preferences files; bug 647109
if fnmatch.fnmatch(name, "defaults/preferences/*.js"):
match = PASSWORD_REGEX.search(file_data)
if match:
context = ContextGenerator(file_data)
err.warning(
err_id=("testcases_content",
"test_packed_packages",
"password_in_js"),
warning="Passwords may be stored in defaults/"
"preferences JS files",
description="Storing passwords in the preferences "
"is insecure and the Login Manager "
"should be used instead.",
filename=name,
line=context.get_line(match.start()),
context=context)
testendpoint_js.test_js_file(err, name, file_data)
run_regex_tests(file_data, err, name)
return False

Просмотреть файл

@ -1,6 +1,7 @@
import re
from validator.constants import BUGZILLA_BUG
from validator.contextgenerator import ContextGenerator
from validator.decorator import versions_after
@ -13,7 +14,7 @@ GENERIC_PATTERNS = {
r"globalStorage\[.*\].password":
"Global Storage may not be used to store passwords.",
r"browser\.preferences\.instantApply":
"Changing the value of instantApply can leat to UI problems in the "
"Changing the value of instantApply can lead to UI problems in the "
"browser.",
r"network\.http": NP_WARNING,
r"network\.websocket": "Websocket preferences should not be modified.",
@ -69,9 +70,12 @@ FX7_DEFINITION = {"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}":
versions_after("firefox", "7.0a1")}
def run_regex_tests(document, err, filename, context):
def run_regex_tests(document, err, filename, context=None):
"""Run all of the regex-based JS tests."""
if context is None:
context = ContextGenerator(document)
def _generic_test(pattern, title, message):
"""Run a single regex test."""
match = pattern.search(document)

Просмотреть файл

@ -7,7 +7,6 @@ import validator.testcases.javascript.traverser as traverser
from validator.testcases.javascript.spidermonkey import get_tree, \
JSReflectException
from validator.constants import PACKAGE_THEME, SPIDERMONKEY_INSTALLATION
from validator.testcases.javascript.regex import run_regex_tests
from validator.contextgenerator import ContextGenerator
from validator.textfilter import *
@ -56,7 +55,6 @@ def test_js_file(err, filename, data, line=0, context=None):
is_jsm=filename.endswith(".jsm") or
"EXPORTED_SYMBOLS" in data)
t.run(tree)
run_regex_tests(data, err, filename, context)
# Reset the tier so we don't break the world
if err is not None: