Mozilla Web App Validator
Перейти к файлу
Matt Basta 3436672f3a Even better handling of redirects and duplicate HTTP requests. 2013-01-07 13:46:53 -08:00
appvalidator Even better handling of redirects and duplicate HTTP requests. 2013-01-07 13:46:53 -08:00
extras jQuery fetcher updates 2012-11-09 14:24:55 -08:00
scripts Cleaner way to find out where tracemonkey is. 2011-10-21 02:27:14 +08:00
tests Even better handling of redirects and duplicate HTTP requests. 2013-01-07 13:46:53 -08:00
.gitignore Second pass 2012-08-01 15:43:36 -07:00
.travis.yml Hello, Travis 2012-10-02 17:28:57 -07:00
LICENSE Updated app validator license 2012-08-06 11:36:18 -07:00
MANIFEST.in Initial naive pass at forking the validator 2012-08-01 13:22:58 -07:00
README.rst Ripped out the stuff I found from the perfalator 2012-11-27 14:35:11 -08:00
app-validator Got validation flow up and running 2012-08-06 13:27:56 -07:00
fabfile.py Minor tweaks to make setup easier 2010-07-13 16:07:35 -07:00
griz.py Updated grizwald endpoint 2012-08-15 11:28:24 -07:00
jsmain.py Made jsmain work, fixed document.write() noise 2012-11-28 14:02:59 -08:00
requirements.txt Added PIL requirement because it was missing. 2012-10-02 17:32:22 -07:00
setup.py Initial naive pass at forking the validator 2012-08-01 13:22:58 -07:00

README.rst

===================================
 marketplace.mozilla.org Validator
===================================

The Apps Validator is a tool designed to scan open web apps for
problems and invalid code. By using a combination of various techniques and
detection mechanisms, the validator is capable of being both efficient as well
as thorough.

-------
 Setup
-------

Prerequisites
=============

Python Libraries:

- argparse
- cssutils
- fastchardet

Python Libraries for Testing:

- nose
- coverage

You can install everything you need for running and testing with ::

    pip install -r requirements.txt


Submodules
==========

The validator may require some submodules to work. Make sure to run ::

    git clone --recursive git://github.com/mozilla/app-validator.git

so that you get all of the goodies inside.


Spidermonkey
============

A working copy of Spidermonkey (debug or non-debug is fine) is required. The
version installed must include support for the Parser API. At the time of this
writing the version of Spidermonkey included with major package managers does
not yet include the Parser API.

How do you know if your js binary has the Parser API? Run this::

    js -e 'Reflect;'

There should be no error output.

The best way to make sure you install the right Spidermonkey is to `clone`_ the
mozilla-central repo or `download the tip`_ (which is faster). Then build it
from source like this::

    cd mozilla-central
    cd js/src
    autoconf2.13
    ./configure
    make
    sudo cp dist/bin/js /usr/local/bin/js

You must use autoconf at *exactly* 2.13 or else it won't work. If you're using
`brew`_ on Mac OS X you can get autoconf2.13 with this::

    brew install https://gist.github.com/raw/765545/c87a75f2cf9e26c153970522e227f1c1cf63fb81/autoconf213.rb

If you don't want to put the ``js`` executable in your ``$PATH`` or you want it
in a custom path, you can define it as ``$SPIDERMONKEY_INSTALLATION`` in
your environment.

.. _`brew`: http://mxcl.github.com/homebrew/
.. _`clone`: http://hg.mozilla.org/mozilla-central/
.. _`download the tip`: http://hg.mozilla.org/mozilla-central/archive/tip.tar.bz2

---------
 Running
---------

Run the validator as follows ::

    python app-validator <path to app> [-o <output type>] [-v] [--boring] [--selfhosted]

The path to the XPI should point to an XPI file.

-o                  The type of output to generate. Types are listed below.
-v                  Enable verbose mode. Extra information will be displayed in
                    verbose mode, namely notices (informational messages),
                    Jetpack information if available, extra error info (like
                    contexts, file data, etc.), and error descriptions. This
                    only applies to ``-o text``.
--unlisted          Disables messages that are specific to apps hosted on
                    Marketplace.
--boring            Disables colorful shell output.

Output Type:
============

The output type may be either of the following:

text (default)
    Outputs a textual summary of the addo-on analysis. Supports verbose mode.
json
    Outputs a JSON snippet representing a full summary of the analysis.


--------
 Output
--------

Text Output Mode:
=================

In ``text`` output mode, output is structured in the format of one
message per line. The messages are prefixed by their priority level
(i.e.: "Warning: This is the message").

At the head of the text output is a block describing what the app type was
determined to be.


JSON Output Mode:
=================

In ``JSON`` output mode, output is formatted as a JSON snippet
containing all messages. The format for the JSON output is that of the
sample document below.

::

    {
        "detected_type": "packaged_app",
        "errors": 2,
        "warnings": 1,
        "notices": 1,
        "success": false,
        "ending_tier": 4,
        "messages": [
            {
                "uid": "123456789",
                "id": ["module", "function", "error"],
                "type": "error",
                "message": "This is the error message text.",
                "description": ["Description of the error message.",
                                "Additional description text"],
                "file": "chrome/foo.bar",
                "line": 12,
                "column": 50,
                "context: [
                    "   if(foo = bar())",
                    "       an_error_is_somewhere_on_this_line.prototy.eval("whatever");",
                    null
                ],
                "tier": 2
            }
        ]
    }


JSON Notes:
-----------

File Hierarchy
~~~~~~~~~~~~~~

When a subpackage exists, an angle bracket will delimit the subpackage
name and the message text.

If no applicable file is available (i.e.: when a file is missing), the
``file`` value will be empty. If a ``file`` value is available within a
subpackage, then the ``file`` attribute will be a list containing the
name of the outermost subpackage's name, followed by each successive
concentric subpackage's name, followed by the name of the file that the
message was generated in. If no applicable file is available within a
subpackage, the ``file`` attribute is identical, except the last element
of the list in the ``file`` attribute is an empty string.

For instance, this tree would generate the following messages:

::

    package_to_test.xpi
        |
        |-install.rdf
        |-chrome.manifest
        |-subpackage.xpi
        |  |
        |  |-subsubpackage.xpi
        |     |
        |     |-chrome.manifest
        |     |-install.rdf
        |
        |-subpackage.jar
           |
           |-install.rdf

::

    {
        "type": "notice",
        "message": "<em:type> not found in install.rdf",
        "description": " ... ",
        "file": "install.rdf",
        "line": 0
    },
    {
        "type": "error",
        "message": "Invalid chrome.manifest subject: override",
        "description": " ... ",
        "file": "chrome.manifest",
        "line": 7
    },
    {
        "type": "error",
        "message": "subpackage.xpi > install.rdf missing from theme",
        "description": " ... ",
        "file": ["subpackage.xpi", ""],
        "line": 0
    },
    {
        "type": "error",
        "message": "subpackage.xpi > subsubpackage.xpi > Invalid chrome.manifest subject: sytle",
        "description": " ... ",
        "file": ["subpackage.xpi", "subsubpackage.xpi", "chrome.manifest"],
        "line": 5
    }

Line Numbers and Columns
~~~~~~~~~~~~~~~~~~~~~~~~

Line numbers are 1-based. Column numbers are 0-based. This can be
confusing from a programmatic standpoint, but makes literal sense. "Line
one" would obviously refer to the first line of a file.

Contexts
~~~~~~~~

The context attribute of messages will either be a list or null. Null
contexts represent the validator's inability to determine surrounding
code. As a list, there will always be three elements. Each element
represents a line surrounding the message's location.

The middle element of the context list represents the line of interest. If
an element of the context list is null, that line does not exist. For
instance, if an error is on the first line of a file, the context might
look like:

::

    [
        null,
        "This is the line with the error",
        "This is the second line of the file"
    ]

The same rule applies for the end of a file and for files with only one line.

---------
 Testing
---------

Unit tests can be run with ::

    fab test

or, after setting the proper python path: ::

    nosetests

----------
 Updating
----------

Some regular maintenance needs to be performed on the validator in order to
make sure that the results are accurate.

JS Libraries
============

A list of JS library hashes is kept to allow for whitelisting. This must be
regenerated with each new library version. To update: ::

    cd extras
    mkdir jslibs
    python jslibfetcher.py
    python build_whitelist.py jslibs/
    # We keep a special hash for testing
    echo "e96461c6c19608f528b4a3c33a032b697b999b62" >> whitelist_hashes.txt
    mv whitelist_hashes.txt ../validator/testcases/hashes.txt

To add new libraries to the mix, edit ``extras/jslibfetcher.py`` and add the
version number to the appropriate tuple.