contrib/check-config.py
author Matt Mackall <mpm@selenic.com>
Tue, 01 Sep 2015 16:08:07 -0500
branchstable
changeset 26120 1a45e49a6bed
parent 25849 d1cb185b9ee2
child 27310 9c98fe1416c2
permissions -rwxr-xr-x
hgweb: fix trust of templates path (BC) Long ago we disabled trust of the templates path with a comment describing the (insecure) behavior before the change. At some later refactor, the code was apparently changed back to match the comment, unaware that the intent of the comment was to describe the behavior to avoid. This change disables the trust and updates the comment to explicitly say not only what the old problem was, but also that it was in fact a problem and the action taken to prevent it. Impact: prior to this change, if you had a UNIX-based hgweb server where users can write hgrc files, those users could potentially read any file readable by the web server. This is marked as a backwards compatibility issue because people may have configured templates without proper trust settings. Issue spotted by Greg Szorc.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
#!/usr/bin/env python
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# check-config - a config flag documentation checker for Mercurial
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# Copyright 2015 Matt Mackall <mpm@selenic.com>
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
#
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
import re
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
import sys
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
foundopts = {}
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
documented = {}
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
configre = (r"""ui\.config(|int|bool|list)\(['"](\S+)['"], ?"""
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
            r"""['"](\S+)['"](,\s(?:default=)?(\S+?))?\)""")
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
def main(args):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    for f in args:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
        sect = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
        prevname = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
        confsect = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
        for l in open(f):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
            # check topic-like bits
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
            m = re.match('\s*``(\S+)``', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
                prevname = m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
            if re.match('^\s*-+$', l):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
                sect = prevname
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
                prevname = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
            if sect and prevname:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
                name = sect + '.' + prevname
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
                documented[name] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
            # check docstring bits
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
            m = re.match(r'^\s+\[(\S+)\]', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
                confsect = m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
                continue
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
            m = re.match(r'^\s+(?:#\s*)?([a-z._]+) = ', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
                name = confsect + '.' + m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
                documented[name] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
            # like the bugzilla extension
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
            m = re.match(r'^\s*([a-z]+\.[a-z]+)$', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
                documented[m.group(1)] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
            # quoted in help or docstrings
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
            m = re.match(r'.*?``([-a-z_]+\.[-a-z_]+)``', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
                documented[m.group(1)] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            # look for ignore markers
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
            m = re.search(r'# (?:internal|experimental|deprecated|developer)'
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
                          ' config: (\S+.\S+)$', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
                documented[m.group(1)] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            # look for code-like bits
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
            m = re.search(configre, l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
            if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
                ctype = m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
                if not ctype:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
                    ctype = 'str'
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
                name = m.group(2) + "." + m.group(3)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
                default = m.group(5)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
                if default in (None, 'False', 'None', '0', '[]', '""', "''"):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
                    default = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
                if re.match('[a-z.]+$', default):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
                    default = '<variable>'
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
                if name in foundopts and (ctype, default) != foundopts[name]:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
                    print l
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
                    print "conflict on %s: %r != %r" % (name, (ctype, default),
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
                                                        foundopts[name])
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
                foundopts[name] = (ctype, default)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
    for name in sorted(foundopts):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
        if name not in documented:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
            if not (name.startswith("devel.") or
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
                    name.startswith("experimental.") or
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
                    name.startswith("debug.")):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
                ctype, default = foundopts[name]
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
                if default:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
                    default = ' [%s]' % default
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
                print "undocumented: %s (%s)%s" % (name, ctype, default)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
if __name__ == "__main__":
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
    sys.exit(main(sys.argv[1:]))