示例#1
0
def _test(script):
    err = ErrorBundle()
    err.supported_versions = {}
    err.save_resource("em:bootstrap", "true")
    scripting.test_js_file(err, "foo", script)

    return err
def _test(script):
    err = ErrorBundle()
    err.supported_versions = {}
    err.save_resource('em:bootstrap', 'true')
    scripting.test_js_file(err, 'foo', script)

    return err
示例#3
0
def set_contentScript(value, traverser):
    """Warns when values are assigned to the `contentScript` properties,
    which are essentially the same as calling `eval`."""

    if value.is_literal():
        content_script = actions._get_as_str(value)

        # Avoid import loop.
        from validator.testcases.scripting import test_js_file
        test_js_file(traverser.err,
                     traverser.filename,
                     content_script,
                     line=traverser.line,
                     context=traverser.context)
    else:
        traverser.warning(
            err_id=('testcases_javascript_instanceproperties', 'contentScript',
                    'set_non_literal'),
            warning='`contentScript` properties should not be used',
            description='Creating content scripts from dynamic values '
            'is dangerous and error-prone. Please use a separate '
            'JavaScript file, along with the '
            '`contentScriptFile` property instead.',
            signing_help='Please do not use the `contentScript` property '
            'in any add-ons submitted for automated signing.',
            signing_severity='high')
def PageMod(args, traverser, node, wrapper):
    """
    This is the function that is called in Jetpack to modify the contents of a
    page with a "content script". This function needs to analyze he first
    parameter. If it is an object and if that object contains a "contentScript"
    string, that string needs to be passed to the validator.testcases.scripting
    library for testing as its own JS script file.
    """

    if not args:
        return

    pm_properties = traverser._traverse_node(args[0])
    if not pm_properties.has_property("contentScript"):
        return

    content_script = pm_properties.get(traverser, "contentScript")
    if not content_script.is_literal():
        return
    content_script = actions._get_as_str(content_script.get_literal_value())
    if not content_script.strip():
        return

    import validator.testcases.scripting as sub_scripting
    sub_scripting.test_js_file(
            traverser.err, traverser.filename, content_script,
            line=traverser.line, context=traverser.context)
示例#5
0
def PageMod(args, traverser, node, wrapper):
    """
    This is the function that is called in Jetpack to modify the contents of a
    page with a "content script". This function needs to analyze he first
    parameter. If it is an object and if that object contains a "contentScript"
    string, that string needs to be passed to the validator.testcases.scripting
    library for testing as its own JS script file.
    """

    if not args:
        return

    pm_properties = traverser._traverse_node(args[0])
    if not pm_properties.has_property("contentScript"):
        return

    content_script = pm_properties.get(traverser, "contentScript")
    if not content_script.is_literal():
        return
    content_script = actions._get_as_str(content_script.get_literal_value())
    if not content_script.strip():
        return

    import validator.testcases.scripting as sub_scripting
    sub_scripting.test_js_file(
        traverser.err, traverser.filename, content_script,
        line=traverser.line, context=traverser.context)
def _test(script):
    err = ErrorBundle()
    err.supported_versions = {}
    err.save_resource("em:bootstrap", "true")
    scripting.test_js_file(err, "foo", script)

    return err
示例#7
0
def _test(script):
    err = ErrorBundle()
    err.supported_versions = {}
    err.save_resource('em:bootstrap', 'true')
    scripting.test_js_file(err, 'foo', script)

    return err
示例#8
0
def test_packed_scripts(err, xpi_package):
    """
    Scripts must be tested separately from normal files to allow for markup
    files to mark scripts as being potentially polluting.
    """

    # This test doesn't apply to subpackages. We keep references to the
    # subpackage bundles so we can process everything at once in an unpushed
    # state.
    if err.is_nested_package():
        return

    scripts = err.get_resource("scripts")
    if not scripts:
        return

    # Get the chrome manifest in case there's information about pollution
    # exemptions.
    chrome = err.get_resource("chrome.manifest_nopush")
    marked_scripts = err.get_resource("marked_scripts")
    if not marked_scripts:
        marked_scripts = set()

    # Process all of the scripts that were found seperately from the rest of
    # the package contents.
    for script_bundle in scripts:
        package = script_bundle["package"]

        # Set the error bundle's package state to what it was when we first
        # encountered the script file during the content tests.
        err.package_stack = script_bundle["state"]

        for script in script_bundle["scripts"]:
            file_data = unicodehelper.decode(package.read(script))

            if marked_scripts:
                reversed_script = chrome.reverse_lookup(script_bundle["state"],
                                                        script)
                # Run the standard script tests on the script, but mark the
                # script as pollutable if its chrome URL is marked as being so.
                testendpoint_js.test_js_file(
                        err, script, file_data,
                        pollutable=reversed_script in marked_scripts)
            else:
                # Run the standard script tests on the scripts.
                testendpoint_js.test_js_file(err, script, file_data)
            run_regex_tests(file_data, err, script, is_js=True)

    # We only run this testcase if the package stack is empty, return it to its
    # original state.
    err.package_stack = []
def test_scripting_disabled():
    "Ensures that Spidermonkey is not run if it is set to be disabled"

    err = ErrorBundle()
    err.save_resource("SPIDERMONKEY", None)
    assert scripting.test_js_file(err, "abc def", "foo bar") is None

    err = ErrorBundle()
    si = scripting.SPIDERMONKEY_INSTALLATION
    scripting.SPIDERMONKEY_INSTALLATION = None

    assert scripting.test_js_file(err, "abc def", "foo bar") is None

    scripting.SPIDERMONKEY_INSTALLATION = si
示例#10
0
def test_scripting_disabled():
    "Ensures that Spidermonkey is not run if it is set to be disabled"

    err = ErrorBundle()
    err.save_resource("SPIDERMONKEY", None)
    assert scripting.test_js_file(err, "abc def", "foo bar") is None

    err = ErrorBundle()
    si = scripting.SPIDERMONKEY_INSTALLATION
    scripting.SPIDERMONKEY_INSTALLATION = None

    assert scripting.test_js_file(err, "abc def", "foo bar") is None

    scripting.SPIDERMONKEY_INSTALLATION = si
def set_contentScript(value, traverser):
    """Warns when values are assigned to the `contentScript` properties,
    which are essentially the same as calling `eval`."""

    if value.is_literal():
        content_script = actions._get_as_str(value)

        # Avoid import loop.
        from validator.testcases.scripting import test_js_file
        test_js_file(
            traverser.err, traverser.filename, content_script,
            line=traverser.line, context=traverser.context)
    else:
        traverser.warning(
            err_id=("testcases_javascript_instanceproperties",
                    "contentScript", "set_non_literal"),
            warning="`contentScript` properties should not be used",
            description="Creating content scripts from dynamic values "
                        "is dangerous and error-prone. Please use a separate "
                        "JavaScript file, along with the "
                        "`contentScriptFile` property instead.",
            signing_severity="high")
def set_contentScript(value, traverser):
    """Warns when values are assigned to the `contentScript` properties,
    which are essentially the same as calling `eval`."""

    if value.is_literal():
        content_script = actions._get_as_str(value)

        # Avoid import loop.
        from validator.testcases.scripting import test_js_file
        test_js_file(
            traverser.err, traverser.filename, content_script,
            line=traverser.line, context=traverser.context)
    else:
        traverser.warning(
            err_id=('testcases_javascript_instanceproperties',
                    'contentScript', 'set_non_literal'),
            warning='`contentScript` properties should not be used',
            description='Creating content scripts from dynamic values '
                        'is dangerous and error-prone. Please use a separate '
                        'JavaScript file, along with the '
                        '`contentScriptFile` property instead.',
            signing_help='Please do not use the `contentScript` property '
                         'in any add-ons submitted for automated signing.',
            signing_severity='high')
示例#13
0
def _process_file(err,
                  xpi_package,
                  name,
                  file_data,
                  name_lower,
                  pollutable=False):
    """Process a single file's content tests."""

    extension = os.path.splitext(name_lower)[1]

    # If that item is a container file, unzip it and scan it.
    if extension == '.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 BadZipfile:
            err.error(('testcases_content', 'test_packed_packages',
                       'jar_subpackage_corrupt'), 'Subpackage corrupt.',
                      'The subpackage appears to be corrupt, and could not '
                      'be opened.', name)
            return

        # Let the error bunder know we're in a sub-package.
        err.push_state(name)
        err.detected_type = (PACKAGE_SUBPACKAGE
                             if is_subpackage else PACKAGE_THEME)
        err.set_tier(1)
        supported_versions = (err.supported_versions.copy()
                              if err.supported_versions else
                              err.supported_versions)

        if is_subpackage:
            testendpoint_validator.test_inner_package(err, sub_xpi)
        else:
            testendpoint_validator.test_package(err, package, name)

        err.pop_state()
        err.set_tier(2)

        err.supported_versions = supported_versions

    elif extension == '.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)

        err.pop_state()
        err.set_tier(2)  # Reset to the current tier

    else:

        if not file_data:
            return

        # Convert the file data to unicode.
        file_data = unicodehelper.decode(file_data)

        if extension in ('.js', '.jsm'):
            testendpoint_js.test_js_file(err,
                                         name,
                                         file_data,
                                         pollutable=pollutable)
        elif extension == '.css':
            testendpoint_css.test_css_file(err, name, file_data)

        run_regex_tests(file_data, err, filename=name)
示例#14
0
def test_packed_scripts(err, xpi_package):
    """
    Scripts must be tested separately from normal files to allow for markup
    files to mark scripts as being potentially polluting.
    """

    # This test doesn't apply to subpackages. We keep references to the
    # subpackage bundles so we can process everything at once in an unpushed
    # state.
    if err.is_nested_package:
        return

    scripts = err.get_resource('scripts')
    if not scripts:
        return

    total_scripts = sum(len(bundle['scripts']) for bundle in scripts)
    exhaustive = True
    if total_scripts > MAX_JS_THRESHOLD:
        err.warning(
            err_id=('testcases_content', 'packed_js', 'too_much_js'),
            warning='TOO MUCH JS FOR EXHAUSTIVE VALIDATION',
            description='There are too many JS files for the validator to '
            'process sequentially. An editor must manually '
            'review the JS in this add-on.')
        exhaustive = False

    # Get the chrome manifest in case there's information about pollution
    # exemptions.
    chrome = err.get_resource('chrome.manifest_nopush')
    marked_scripts = err.get_resource('marked_scripts')
    if not marked_scripts:
        marked_scripts = set()

    # Process all of the scripts that were found seperately from the rest of
    # the package contents.
    for script_bundle in scripts:
        package = script_bundle['package']

        # Set the error bundle's package state to what it was when we first
        # encountered the script file during the content tests.
        for archive in script_bundle['state']:
            err.push_state(archive)

        for script in script_bundle['scripts']:
            file_data = unicodehelper.decode(package.read(script))

            run_regex_tests(file_data, err, script)
            # If we're not running an exhaustive set of tests, skip the full JS
            # parse and traversal.
            if not exhaustive:
                continue

            if marked_scripts:
                reversed_script = chrome.reverse_lookup(
                    script_bundle['state'], script)
                # Run the standard script tests on the script, but mark the
                # script as pollutable if its chrome URL is marked as being so.
                testendpoint_js.test_js_file(err,
                                             script,
                                             file_data,
                                             pollutable=reversed_script
                                             in marked_scripts)
            else:
                # Run the standard script tests on the scripts.
                testendpoint_js.test_js_file(err, script, file_data)

        for i in range(len(script_bundle['state'])):
            err.pop_state()
示例#15
0
def _process_file(err, xpi_package, name, file_data, name_lower,
                  pollutable=False):
    """Process a single file's content tests."""

    # 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 Exception:
            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)
        err.detected_type = (PACKAGE_SUBPACKAGE if is_subpackage else
                             PACKAGE_THEME)
        err.set_tier(1)
        supported_versions = (err.supported_versions.copy() if
                              err.supported_versions else
                              err.supported_versions)

        if is_subpackage:
            testendpoint_validator.test_inner_package(err, sub_xpi)
        else:
            testendpoint_validator.test_package(err, package, name)

        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)

        err.pop_state()
        err.set_tier(2)  # Reset to the current tier

    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)
        is_js = False

        if name_lower.endswith(".css"):
            testendpoint_css.test_css_file(err, name, file_data)

        elif name_lower.endswith((".js", ".jsm")):
            is_js = True
            testendpoint_js.test_js_file(err, name, file_data,
                                         pollutable=pollutable)

        run_regex_tests(file_data, err, name, is_js=is_js)

        return True

    return False
示例#16
0
def test_packed_scripts(err, xpi_package):
    """
    Scripts must be tested separately from normal files to allow for markup
    files to mark scripts as being potentially polluting.
    """

    # This test doesn't apply to subpackages. We keep references to the
    # subpackage bundles so we can process everything at once in an unpushed
    # state.
    if err.is_nested_package:
        return

    scripts = err.get_resource("scripts")
    if not scripts:
        return

    total_scripts = sum(len(bundle["scripts"]) for bundle in scripts)
    exhaustive = True
    if total_scripts > MAX_JS_THRESHOLD:
        err.warning(
            err_id=("testcases_content", "packed_js", "too_much_js"),
            warning="TOO MUCH JS FOR EXHAUSTIVE VALIDATION",
            description="There are too many JS files for the validator to "
                        "process sequentially. An editor must manually "
                        "review the JS in this add-on.")
        exhaustive = False

    # Get the chrome manifest in case there's information about pollution
    # exemptions.
    chrome = err.get_resource("chrome.manifest_nopush")
    marked_scripts = err.get_resource("marked_scripts")
    if not marked_scripts:
        marked_scripts = set()

    # Process all of the scripts that were found seperately from the rest of
    # the package contents.
    for script_bundle in scripts:
        package = script_bundle["package"]

        # Set the error bundle's package state to what it was when we first
        # encountered the script file during the content tests.
        for archive in script_bundle["state"]:
            err.push_state(archive)

        for script in script_bundle["scripts"]:
            file_data = unicodehelper.decode(package.read(script))

            run_regex_tests(file_data, err, script, is_js=True)
            # If we're not running an exhaustive set of tests, skip the full JS
            # parse and traversal.
            if not exhaustive:
                continue

            if marked_scripts:
                reversed_script = chrome.reverse_lookup(script_bundle["state"],
                                                        script)
                # Run the standard script tests on the script, but mark the
                # script as pollutable if its chrome URL is marked as being so.
                testendpoint_js.test_js_file(
                        err, script, file_data,
                        pollutable=reversed_script in marked_scripts)
            else:
                # Run the standard script tests on the scripts.
                testendpoint_js.test_js_file(err, script, file_data)

        for i in range(len(script_bundle["state"])):
            err.pop_state()
示例#17
0
def _process_file(err, xpi_package, name, file_data, name_lower,
                  pollutable=False):
    """Process a single file's content tests."""

    # 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 BadZipfile:
            err.error(('testcases_content',
                       'test_packed_packages',
                       'jar_subpackage_corrupt'),
                      'Subpackage corrupt.',
                      'The subpackage appears to be corrupt, and could not '
                      'be opened.',
                      name)
            return None

        # Let the error bunder know we're in a sub-package.
        err.push_state(name)
        err.detected_type = (PACKAGE_SUBPACKAGE if is_subpackage else
                             PACKAGE_THEME)
        err.set_tier(1)
        supported_versions = (err.supported_versions.copy() if
                              err.supported_versions else
                              err.supported_versions)

        if is_subpackage:
            testendpoint_validator.test_inner_package(err, sub_xpi)
        else:
            testendpoint_validator.test_package(err, package, name)

        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)

        err.pop_state()
        err.set_tier(2)  # Reset to the current tier

    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)
        is_js = name_lower.endswith(('.js', '.jsm'))

        if name_lower.endswith('.css'):
            testendpoint_css.test_css_file(err, name, file_data)

        elif is_js:
            testendpoint_js.test_js_file(err, name, file_data,
                                         pollutable=pollutable)

        run_regex_tests(file_data, err, name, is_js=is_js)

        return True

    else:
        if file_data:
            file_data = unicodehelper.decode(file_data)
            run_regex_tests(file_data, err, name, explicit=True)

    return False
示例#18
0
def test_packed_packages(err, package_contents=None, xpi_package=None):
    "Tests XPI and JAR files for naughty content."
    
    processed_files = 0

    hash_whitelist = [x[:-1] for x in
                      open(os.path.join(os.path.dirname(__file__),
                                        'whitelist_hashes.txt')).readlines()]
    
    # Iterate each item in the package.
    for name, data in package_contents.items():
        
        if name.startswith("__MACOSX") or \
           name.startswith(".DS_Store"):
            continue
        
        if name.split("/")[-1].startswith("._"):
            err.notice(("testcases_content",
                        "test_packed_packages",
                        "macintosh_junk"),
                       "Garbage file found.",
                       ["""A junk file has been detected. It may cause
                        problems with proper operation of the add-on down the
                        road.""",
                        "It is recommended that you delete the file"],
                       name)
        
        try:
            file_data = xpi_package.read(name)
        except KeyError: # pragma: no cover
            _read_error(err, name)

        # Skip over whitelisted hashes
        hash = hashlib.sha1(file_data).hexdigest()
        if hash in hash_whitelist:
            continue

        processed = False
        # If that item is a container file, unzip it and scan it.
        if data["extension"] == "jar":
            # This is either a subpackage or a nested theme.
            
            # Whether this is a subpackage or a nested theme is
            # determined by whether it is in the root folder or not.
            # Subpackages are always found in a directory such as
            # /chrome or /content.
            is_subpackage = name.count("/") > 0
            
            # Unpack the package and load it up.
            package = StringIO(file_data)
            sub_xpi = XPIManager(package, name, is_subpackage)
            if not sub_xpi.zf:
                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
            
            temp_contents = sub_xpi.get_file_data()
            
            # Let the error bunder know we're in a sub-package.
            err.push_state(data["name_lower"])
            err.set_type(PACKAGE_SUBPACKAGE) # Subpackage
            testendpoint_validator.test_inner_package(err,
                                                      temp_contents,
                                                      sub_xpi)
            err.tier = 2
            package.close()
            err.pop_state()
            
        elif data["extension"] == "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(data["name_lower"])
            

            # There are no expected types for packages within a multi-
            # item package.
            testendpoint_validator.test_package(err, package, name)
            err.tier = 2 # Reset to the current tier
            
            package.close()
            err.pop_state()
            
        elif data["extension"] in ("xul", "xml", "html", "xhtml"):
            
            parser = testendpoint_markup.MarkupParser(err)
            parser.process(name,
                           charsethelper.decode(file_data),
                           data["extension"])
            
            processed = True
                
            
        elif data["extension"] in ("css", "js", "jsm"):
            
            if not file_data:
                continue
            file_data = charsethelper.decode(file_data)
            
            if data["extension"] == "css":
                testendpoint_css.test_css_file(err,
                                               name,
                                               file_data)
            elif data["extension"] in ("js", "jsm"):
                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)
        
        # This aids in creating unit tests.
        processed_files += 1
            
    return processed_files
示例#19
0
from validator.outputhandlers.shellcolors import OutputHandler
import validator.testcases.scripting as scripting
import validator.testcases.javascript.traverser
from validator.testcases.javascript.predefinedentities import GLOBAL_ENTITIES
import validator.testcases.javascript.spidermonkey as spidermonkey
validator.testcases.javascript.traverser.DEBUG = True

if __name__ == '__main__':
    err = ErrorBundle(instant=True)
    err.handler = OutputHandler(sys.stdout, False)
    err.supported_versions = {}
    if len(sys.argv) > 1:
        path = sys.argv[1]
        script = open(path).read()
        scripting.test_js_file(err=err,
                               filename=path,
                               data=script)
    else:
        trav = validator.testcases.javascript.traverser.Traverser(err, "stdin")
        trav._push_context()

        def do_inspect(wrapper, arguments, traverser):
            print "~" * 50
            for arg in arguments:
                if arg["type"] == "Identifier":
                    print 'Identifier: "%s"' % arg["name"]
                else:
                    print arg["type"]

                a = traverser._traverse_node(arg)
                print a.output()
示例#20
0
def test_valid():
    err = ErrorBundle(None, True)
    data = open("tests/resources/bug_590992_valid.js").read()
    scripting.test_js_file(err=err, filename="test", data=data)

    assert not err.failed()
示例#21
0
from validator.outputhandlers.shellcolors import OutputHandler
import validator.testcases.scripting as scripting
import validator.testcases.javascript.traverser
from validator.testcases.javascript.predefinedentities import GLOBAL_ENTITIES
import validator.testcases.javascript.spidermonkey as spidermonkey
validator.testcases.javascript.traverser.DEBUG = True

if __name__ == '__main__':
    err = ErrorBundle(instant=True)
    err.handler = OutputHandler(sys.stdout, False)
    err.supported_versions = {}
    if len(sys.argv) > 1:
        path = sys.argv[1]
        script = open(path).read()
        scripting.test_js_file(err=err,
                               filename=path,
                               data=script)
    else:
        trav = validator.testcases.javascript.traverser.Traverser(err, "stdin")
        trav._push_context()

        def do_inspect(wrapper, arguments, traverser):
            print "~" * 50
            for arg in arguments:
                if arg["type"] == "Identifier":
                    print 'Identifier: "%s"' % arg["name"]
                else:
                    print arg["type"]

                a = traverser._traverse_node(arg)
                print a.output()
示例#22
0
def _process_file(err,
                  xpi_package,
                  name,
                  file_data,
                  name_lower,
                  pollutable=False):
    """Process a single file's content tests."""

    # 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 Exception:
            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)
        err.detected_type = (PACKAGE_SUBPACKAGE
                             if is_subpackage else PACKAGE_THEME)
        err.set_tier(1)
        supported_versions = (err.supported_versions.copy()
                              if err.supported_versions else
                              err.supported_versions)

        if is_subpackage:
            testendpoint_validator.test_inner_package(err, sub_xpi)
        else:
            testendpoint_validator.test_package(err, package, name)

        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)

        err.pop_state()
        err.set_tier(2)  # Reset to the current tier

    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)
        is_js = False

        if name_lower.endswith(".css"):
            testendpoint_css.test_css_file(err, name, file_data)

        elif name_lower.endswith((".js", ".jsm")):
            is_js = True
            testendpoint_js.test_js_file(err,
                                         name,
                                         file_data,
                                         pollutable=pollutable)

        run_regex_tests(file_data, err, name, is_js=is_js)

        return True

    return False
示例#23
0
    def handle_endtag(self, tag):

        tag = tag.lower()
        if tag == 'xul:script':
            tag = 'script'

        if tag == 'script' and len(self.xml_buffer[-1]) > 1000:
            self.err.warning(('markup', 'complex_script'),
                             'Long inline script',
                             'Please store complex scripts in .js files '
                             'rather than inline script nodes.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)

        if DEBUG:  # pragma: no cover
            print 'E: ', tag, self.xml_state

        if not self.xml_state:
            if 'closing_tags' in self.reported or not self.strict:
                if DEBUG:
                    print 'Unstrict; extra closing tags ------'
                return
            self.err.warning(('markup',
                              'endtag',
                              'extra_closing_tags'),
                             'Markup parsing error',
                             'The markup file has more closing tags than it '
                             'has opening tags.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)
            self.reported.add('closing_tags')
            if DEBUG:  # pragma: no cover
                print 'Too many closing tags ------'
            return

        elif 'script' in self.xml_state[:-1]:
            # If we're in a script tag, nothing else matters. Just rush
            # everything possible into the xml buffer.

            self._save_to_buffer('</' + tag + '>')
            if DEBUG:
                print 'Markup as text in script ------'
            return

        elif tag not in self.xml_state:
            # If the tag we're processing isn't on the stack, then
            # something is wrong.
            self.err.warning(('markup',
                              'endtag',
                              'extra_closing_tags'),
                             'Parse error: tag closed before opened',
                             ['Markup tags cannot be closed before they are '
                              'opened. Perhaps you were just a little '
                              'overzealous with forward-slashes?',
                              'Tag "%s" closed before it was opened' % tag],
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)
            if DEBUG:  # pragma: no cover
                print 'Tag closed before opened ------'
            return

        data_buffer = self.xml_buffer.pop()
        old_state = self.xml_state.pop()
        old_line = self.xml_line_stack.pop()
        old_position = self.xml_position_stack.pop() or (old_line, 0)
        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
        # down to the level of the tag we're actualy closing.
        if old_state != tag and old_state in SELF_CLOSING_TAGS:
            if DEBUG:
                print 'Self closing tag cascading down ------'
            return self.handle_endtag(tag)

        # If this is an XML-derived language, everything must nest
        # properly. No overlapping tags.
        #
        # ^ Oh, basta, you really have no idea, do you...
        if (old_state != tag and
                self.extension[0] == 'x' and
                not self.strict):

            self.err.warning(('markup',
                              'endtag',
                              'invalid_nesting'),
                             'Markup invalidly nested',
                             'It has been determined that the document '
                             'invalidly nests its tags. This is not permitted '
                             'in the specified document type.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)
            if DEBUG:  # pragma: no cover
                print 'Invalid markup nesting ------'

        # Perform analysis on collected data.
        if data_buffer:
            if tag == 'script' and not script_type:
                self.err.add_script_load(self.filename, self.filename)
                scripting.test_js_file(err=self.err, data=data_buffer,
                                       filename=self.filename,
                                       line=old_position[0],
                                       column=old_position[1] + 1,
                                       context=self.context)
            elif tag == 'style':
                csstester.test_css_file(self.err, self.filename, data_buffer,
                                        old_line)
示例#24
0
    def handle_endtag(self, tag):

        tag = tag.lower()
        if tag == 'xul:script':
            tag = 'script'

        if tag == 'script' and len(self.xml_buffer[-1]) > 1000:
            self.err.warning(('markup', 'complex_script'),
                             'Long inline script',
                             'Please store complex scripts in .js files '
                             'rather than inline script nodes.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)

        if DEBUG:  # pragma: no cover
            print 'E: ', tag, self.xml_state

        if not self.xml_state:
            if 'closing_tags' in self.reported or not self.strict:
                if DEBUG:
                    print 'Unstrict; extra closing tags ------'
                return
            self.err.warning(('markup', 'endtag', 'extra_closing_tags'),
                             'Markup parsing error',
                             'The markup file has more closing tags than it '
                             'has opening tags.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)
            self.reported.add('closing_tags')
            if DEBUG:  # pragma: no cover
                print 'Too many closing tags ------'
            return

        elif 'script' in self.xml_state[:-1]:
            # If we're in a script tag, nothing else matters. Just rush
            # everything possible into the xml buffer.

            self._save_to_buffer('</' + tag + '>')
            if DEBUG:
                print 'Markup as text in script ------'
            return

        elif tag not in self.xml_state:
            # If the tag we're processing isn't on the stack, then
            # something is wrong.
            self.err.warning(
                ('markup', 'endtag', 'extra_closing_tags'),
                'Parse error: tag closed before opened', [
                    'Markup tags cannot be closed before they are '
                    'opened. Perhaps you were just a little '
                    'overzealous with forward-slashes?',
                    'Tag "%s" closed before it was opened' % tag
                ],
                self.filename,
                line=self.line,
                context=self.context,
                tier=2)
            if DEBUG:  # pragma: no cover
                print 'Tag closed before opened ------'
            return

        data_buffer = self.xml_buffer.pop()
        old_state = self.xml_state.pop()
        old_line = self.xml_line_stack.pop()
        old_position = self.xml_position_stack.pop() or (old_line, 0)
        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
        # down to the level of the tag we're actualy closing.
        if old_state != tag and old_state in SELF_CLOSING_TAGS:
            if DEBUG:
                print 'Self closing tag cascading down ------'
            return self.handle_endtag(tag)

        # If this is an XML-derived language, everything must nest
        # properly. No overlapping tags.
        #
        # ^ Oh, basta, you really have no idea, do you...
        if (old_state != tag and self.extension[0] == 'x' and not self.strict):

            self.err.warning(('markup', 'endtag', 'invalid_nesting'),
                             'Markup invalidly nested',
                             'It has been determined that the document '
                             'invalidly nests its tags. This is not permitted '
                             'in the specified document type.',
                             self.filename,
                             line=self.line,
                             context=self.context,
                             tier=2)
            if DEBUG:  # pragma: no cover
                print 'Invalid markup nesting ------'

        # Perform analysis on collected data.
        if data_buffer:
            if tag == 'script' and not script_type:
                self.err.add_script_load(self.filename, self.filename)
                scripting.test_js_file(err=self.err,
                                       data=data_buffer,
                                       filename=self.filename,
                                       line=old_position[0],
                                       column=old_position[1] + 1,
                                       context=self.context)
            elif tag == 'style':
                csstester.test_css_file(self.err, self.filename, data_buffer,
                                        old_line)