diff --git a/SOURCES/mercurial-cve-2018-1000132.patch b/SOURCES/mercurial-cve-2018-1000132.patch
new file mode 100644
index 0000000..4f22e0c
--- /dev/null
+++ b/SOURCES/mercurial-cve-2018-1000132.patch
@@ -0,0 +1,1865 @@
+diff -r cceaf7af4c9e hgext/largefiles/uisetup.py
+--- a/hgext/largefiles/uisetup.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/hgext/largefiles/uisetup.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -11,7 +11,7 @@
+ from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \
+     httppeer, localrepo, merge, scmutil, sshpeer, wireproto, revset
+ from mercurial.i18n import _
+-from mercurial.hgweb import hgweb_mod, webcommands
++from mercurial.hgweb import webcommands
+ from mercurial.subrepo import hgsubrepo
+ 
+ import overrides
+@@ -134,9 +134,10 @@
+ 
+     # make putlfile behave the same as push and {get,stat}lfile behave
+     # the same as pull w.r.t. permissions checks
+-    hgweb_mod.perms['putlfile'] = 'push'
+-    hgweb_mod.perms['getlfile'] = 'pull'
+-    hgweb_mod.perms['statlfile'] = 'pull'
++    wireproto.permissions['putlfile'] = 'push'
++    wireproto.permissions['getlfile'] = 'pull'
++    wireproto.permissions['statlfile'] = 'pull'
++    wireproto.permissions['lheads'] = 'pull'
+ 
+     extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
+ 
+diff -r cceaf7af4c9e mercurial/hgweb/hgweb_mod.py
+--- a/mercurial/hgweb/hgweb_mod.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/mercurial/hgweb/hgweb_mod.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -7,7 +7,7 @@
+ # GNU General Public License version 2 or any later version.
+ 
+ import os
+-from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
++from mercurial import ui, hg, hook, error, encoding, templater, util, repoview, wireproto
+ from mercurial.templatefilters import websub
+ from mercurial.i18n import _
+ from common import get_stat, ErrorResponse, permhooks, caching
+@@ -16,15 +16,8 @@
+ from request import wsgirequest
+ import webcommands, protocol, webutil, re
+ 
+-perms = {
+-    'changegroup': 'pull',
+-    'changegroupsubset': 'pull',
+-    'getbundle': 'pull',
+-    'stream_out': 'pull',
+-    'listkeys': 'pull',
+-    'unbundle': 'push',
+-    'pushkey': 'push',
+-}
++# Aliased for API compatibility.
++perms = wireproto.permissions
+ 
+ def makebreadcrumb(url, prefix=''):
+     '''Return a 'URL breadcrumb' list
+@@ -165,8 +158,13 @@
+             try:
+                 if query:
+                     raise ErrorResponse(HTTP_NOT_FOUND)
+-                if cmd in perms:
+-                    self.check_perm(req, perms[cmd])
++
++                req.checkperm = lambda op: self.check_perm(req, op)
++                # Assume commands with no defined permissions are writes /
++                # for pushes. This is the safest from a security perspective
++                # because it doesn't allow commands with undefined semantics
++                # from bypassing permissions checks.
++                req.checkperm(perms.get(cmd, 'push'))
+                 return protocol.call(self.repo, req, cmd)
+             except ErrorResponse, inst:
+                 # A client that sends unbundle without 100-continue will
+diff -r cceaf7af4c9e mercurial/hgweb/protocol.py
+--- a/mercurial/hgweb/protocol.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/mercurial/hgweb/protocol.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -17,6 +17,7 @@
+         self.req = req
+         self.response = ''
+         self.ui = ui
++        self.checkperm = req.checkperm
+     def getargs(self, args):
+         knownargs = self._args()
+         data = {}
+diff -r cceaf7af4c9e mercurial/wireproto.py
+--- a/mercurial/wireproto.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/mercurial/wireproto.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -11,6 +11,10 @@
+ import changegroup as changegroupmod
+ import peer, error, encoding, util, store
+ 
++# Maps wire protocol name to operation type. This is used for permissions
++# checking.
++permissions = {}
++
+ # abstract batching support
+ 
+ class future(object):
+@@ -361,6 +365,15 @@
+                          % (cmd, ",".join(others)))
+     return opts
+ 
++def wireprotocommand(name, args=''):
++    """decorator for wire protocol command"""
++    def register(func):
++        commands[name] = (func, args)
++        return func
++    return register
++
++# TODO define a more appropriate permissions type to use for this.
++permissions['batch'] = 'pull'
+ def batch(repo, proto, cmds, others):
+     repo = repo.filtered("served")
+     res = []
+@@ -372,6 +385,17 @@
+                 n, v = a.split('=')
+                 vals[n] = unescapearg(v)
+         func, spec = commands[op]
++
++        # If the protocol supports permissions checking, perform that
++        # checking on each batched command.
++        # TODO formalize permission checking as part of protocol interface.
++        if util.safehasattr(proto, 'checkperm'):
++            # Assume commands with no defined permissions are writes / for
++            # pushes. This is the safest from a security perspective because
++            # it doesn't allow commands with undefined semantics from
++            # bypassing permissions checks.
++            proto.checkperm(permissions.get(op, 'push'))
++
+         if spec:
+             keys = spec.split()
+             data = {}
+@@ -392,6 +416,7 @@
+         res.append(escapearg(result))
+     return ';'.join(res)
+ 
++permissions['between'] = 'pull'
+ def between(repo, proto, pairs):
+     pairs = [decodelist(p, '-') for p in pairs.split(" ")]
+     r = []
+@@ -399,6 +424,7 @@
+         r.append(encodelist(b) + "\n")
+     return "".join(r)
+ 
++permissions['branchmap'] = 'pull'
+ def branchmap(repo, proto):
+     branchmap = repo.branchmap()
+     heads = []
+@@ -408,6 +434,7 @@
+         heads.append('%s %s' % (branchname, branchnodes))
+     return '\n'.join(heads)
+ 
++permissions['branches'] = 'pull'
+ def branches(repo, proto, nodes):
+     nodes = decodelist(nodes)
+     r = []
+@@ -415,6 +442,7 @@
+         r.append(encodelist(b) + "\n")
+     return "".join(r)
+ 
++permissions['capabilities'] = 'pull'
+ def capabilities(repo, proto):
+     caps = ('lookup changegroupsubset branchmap pushkey known getbundle '
+             'unbundlehash batch').split()
+@@ -432,22 +460,26 @@
+     caps.append('httpheader=1024')
+     return ' '.join(caps)
+ 
++permissions['changegroup'] = 'pull'
+ def changegroup(repo, proto, roots):
+     nodes = decodelist(roots)
+     cg = repo.changegroup(nodes, 'serve')
+     return streamres(proto.groupchunks(cg))
+ 
++permissions['changegroupsubset'] = 'pull'
+ def changegroupsubset(repo, proto, bases, heads):
+     bases = decodelist(bases)
+     heads = decodelist(heads)
+     cg = repo.changegroupsubset(bases, heads, 'serve')
+     return streamres(proto.groupchunks(cg))
+ 
++permissions['debugwireargs'] = 'pull'
+ def debugwireargs(repo, proto, one, two, others):
+     # only accept optional args from the known set
+     opts = options('debugwireargs', ['three', 'four'], others)
+     return repo.debugwireargs(one, two, **opts)
+ 
++permissions['getbundle'] = 'pull'
+ def getbundle(repo, proto, others):
+     opts = options('getbundle', ['heads', 'common'], others)
+     for k, v in opts.iteritems():
+@@ -455,10 +487,12 @@
+     cg = repo.getbundle('serve', **opts)
+     return streamres(proto.groupchunks(cg))
+ 
++permissions['heads'] = 'pull'
+ def heads(repo, proto):
+     h = repo.heads()
+     return encodelist(h) + "\n"
+ 
++permissions['hello'] = 'pull'
+ def hello(repo, proto):
+     '''the hello command returns a set of lines describing various
+     interesting things about the server, in an RFC822-like format.
+@@ -469,12 +503,14 @@
+     '''
+     return "capabilities: %s\n" % (capabilities(repo, proto))
+ 
++permissions['listkeys'] = 'pull'
+ def listkeys(repo, proto, namespace):
+     d = repo.listkeys(encoding.tolocal(namespace)).items()
+     t = '\n'.join(['%s\t%s' % (encoding.fromlocal(k), encoding.fromlocal(v))
+                    for k, v in d])
+     return t
+ 
++permissions['lookup'] = 'pull'
+ def lookup(repo, proto, key):
+     try:
+         k = encoding.tolocal(key)
+@@ -486,9 +522,11 @@
+         success = 0
+     return "%s %s\n" % (success, r)
+ 
++permissions['known'] = 'pull'
+ def known(repo, proto, nodes, others):
+     return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
+ 
++permissions['pushkey'] = 'push'
+ def pushkey(repo, proto, namespace, key, old, new):
+     # compatibility with pre-1.8 clients which were accidentally
+     # sending raw binary nodes rather than utf-8-encoded hex
+@@ -523,6 +561,7 @@
+ def _allowstream(ui):
+     return ui.configbool('server', 'uncompressed', True, untrusted=True)
+ 
++permissions['stream_out'] = 'pull'
+ def stream(repo, proto):
+     '''If the server supports streaming clone, it advertises the "stream"
+     capability with a value representing the version and flags of the repo
+@@ -589,6 +628,7 @@
+ 
+     return streamres(streamer(repo, entries, total_bytes))
+ 
++permissions['unbundle'] = 'push'
+ def unbundle(repo, proto, heads):
+     their_heads = decodelist(heads)
+ 
+diff -r cceaf7af4c9e tests/get-with-headers.py
+--- a/tests/get-with-headers.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/tests/get-with-headers.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -3,6 +3,7 @@
+ """This does HTTP GET requests given a host:port and path and returns
+ a subset of the headers plus the body of the result."""
+ 
++import argparse
+ import httplib, sys
+ 
+ try:
+@@ -12,14 +13,22 @@
+ except ImportError:
+     pass
+ 
+-twice = False
+-if '--twice' in sys.argv:
+-    sys.argv.remove('--twice')
+-    twice = True
+-headeronly = False
+-if '--headeronly' in sys.argv:
+-    sys.argv.remove('--headeronly')
+-    headeronly = True
++parser = argparse.ArgumentParser()
++parser.add_argument('--twice', action='store_true')
++parser.add_argument('--headeronly', action='store_true')
++parser.add_argument('--requestheader', nargs='*', default=[],
++                    help='Send an additional HTTP request header. Argument '
++                         'value is <header>=<value>')
++parser.add_argument('--bodyfile',
++                    help='Write HTTP response body to a file')
++parser.add_argument('host')
++parser.add_argument('path')
++parser.add_argument('show', nargs='*')
++args = parser.parse_args()
++
++twice = args.twice
++headeronly = args.headeronly
++requestheaders = args.requestheader
+ 
+ reasons = {'Not modified': 'Not Modified'} # python 2.4
+ 
+@@ -31,6 +40,10 @@
+     if tag:
+         headers['If-None-Match'] = tag
+ 
++    for header in requestheaders:
++        key, value = header.split('=', 1)
++        headers[key] = value
++
+     conn = httplib.HTTPConnection(host)
+     conn.request("GET", '/' + path, None, headers)
+     response = conn.getresponse()
+@@ -44,16 +57,22 @@
+     if not headeronly:
+         print
+         data = response.read()
+-        sys.stdout.write(data)
++        if args.bodyfile:
++            bodyfh = open(args.bodyfile, 'wb')
++        else:
++            bodyfh = sys.stdout
++        bodyfh.write(data)
+ 
+         if twice and response.getheader('ETag', None):
+             tag = response.getheader('ETag')
+ 
++        if args.bodyfile:
++            bodyfh.close()
+     return response.status
+ 
+-status = request(sys.argv[1], sys.argv[2], sys.argv[3:])
++status = request(args.host, args.path, args.show)
+ if twice:
+-    status = request(sys.argv[1], sys.argv[2], sys.argv[3:])
++    status = request(args.host, args.path, args.show)
+ 
+ if 200 <= status <= 305:
+     sys.exit(0)
+diff -r cceaf7af4c9e tests/killdaemons.py
+--- a/tests/killdaemons.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/tests/killdaemons.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -49,6 +49,10 @@
+         pass
+ 
+ if __name__ == '__main__':
+-    path, = sys.argv[1:]
++    if len(sys.argv) > 1:
++        path, = sys.argv[1:]
++    else:
++        path = os.environ["DAEMON_PIDS"]
++
+     killdaemons(path)
+ 
+diff -r cceaf7af4c9e tests/run-tests.py
+--- a/tests/run-tests.py	Sat Jun 01 17:09:41 2013 -0500
++++ b/tests/run-tests.py	Tue Jul 03 11:25:06 2018 +0200
+@@ -1321,6 +1321,7 @@
+     os.environ["HGPORT"] = str(options.port)
+     os.environ["HGPORT1"] = str(options.port + 1)
+     os.environ["HGPORT2"] = str(options.port + 2)
++    os.environ["LOCALIP"] = '127.0.0.1'
+ 
+     if options.with_hg:
+         INST = None
+diff -r cceaf7af4c9e tests/test-http-permissions.t
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/tests/test-http-permissions.t	Tue Jul 03 11:25:06 2018 +0200
+@@ -0,0 +1,1491 @@
++#require killdaemons
++
++  $ cat > fakeremoteuser.py << EOF
++  > import os
++  > from mercurial.hgweb import hgweb_mod
++  > from mercurial import wireproto
++  > class testenvhgweb(hgweb_mod.hgweb):
++  >     def __call__(self, env, respond):
++  >         # Allow REMOTE_USER to define authenticated user.
++  >         if r'REMOTE_USER' in os.environ:
++  >             env[r'REMOTE_USER'] = os.environ[r'REMOTE_USER']
++  >         # Allow REQUEST_METHOD to override HTTP method
++  >         if r'REQUEST_METHOD' in os.environ:
++  >             env[r'REQUEST_METHOD'] = os.environ[r'REQUEST_METHOD']
++  >         return super(testenvhgweb, self).__call__(env, respond)
++  > hgweb_mod.hgweb = testenvhgweb
++  > 
++  > @wireproto.wireprotocommand('customreadnoperm')
++  > def customread(repo, proto):
++  >     return b'read-only command no defined permissions\n'
++  > @wireproto.wireprotocommand('customwritenoperm')
++  > def customwritenoperm(repo, proto):
++  >     return b'write command no defined permissions\n'
++  > wireproto.permissions['customreadwithperm'] = 'pull'
++  > @wireproto.wireprotocommand('customreadwithperm')
++  > def customreadwithperm(repo, proto):
++  >     return b'read-only command w/ defined permissions\n'
++  > wireproto.permissions['customwritewithperm'] = 'push'
++  > @wireproto.wireprotocommand('customwritewithperm')
++  > def customwritewithperm(repo, proto):
++  >     return b'write command w/ defined permissions\n'
++  > EOF
++
++  $ cat >> $HGRCPATH << EOF
++  > [extensions]
++  > fakeremoteuser = $TESTTMP/fakeremoteuser.py
++  > EOF
++
++  $ hg init test
++  $ cd test
++  $ echo a > a
++  $ hg ci -Ama
++  adding a
++  $ cd ..
++  $ hg clone test test2
++  updating to branch default
++  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
++  $ cd test2
++  $ echo a >> a
++  $ hg ci -mb
++  $ hg book bm -r 0
++  $ cd ../test
++
++web.deny_read=* prevents access to wire protocol for all users
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > deny_read = *
++  > EOF
++
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=capabilities'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=stream_out'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_read=* with REMOTE_USER set still locks out clients
++
++  $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=capabilities'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=stream_out'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_read=<user> denies access to unauthenticated user
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > deny_read = baduser1,baduser2
++  > EOF
++
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_read=<user> denies access to users in deny list
++
++  $ REMOTE_USER=baduser2 hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_read=<user> allows access to authenticated users not in list
++
++  $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  200 Script output follows
++  
++  read-only command w/ defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  pulling from http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_read=* allows reads for unauthenticated users
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > allow_read = *
++  > EOF
++
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  200 Script output follows
++  
++  read-only command w/ defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  pulling from http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_read=* allows read for authenticated user
++
++  $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  200 Script output follows
++  
++  read-only command w/ defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  pulling from http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_read=<user> does not allow unauthenticated users to read
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > allow_read = gooduser
++  > EOF
++
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_read=<user> does not allow user not in list to read
++
++  $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_read=<user> allows read from user in list
++
++  $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  200 Script output follows
++  
++  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b	1
++  publishing	True (no-eol)
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  200 Script output follows
++  
++  read-only command w/ defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  pulling from http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_read takes precedence over web.allow_read
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > allow_read = baduser
++  > deny_read = baduser
++  > EOF
++
++  $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allowpull=false denies read access to repo
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > allowpull = false
++  > EOF
++
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=capabilities'
++  401 pull not authorized
++  
++  0
++  pull not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases'
++  401 pull not authorized
++  
++  0
++  pull not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases'
++  401 pull not authorized
++  
++  0
++  pull not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadwithperm'
++  401 pull not authorized
++  
++  0
++  pull not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg --cwd ../test2 pull http://localhost:$HGPORT/
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++Attempting a write command with HTTP GET fails
++
++  $ cat > .hg/hgrc <<EOF
++  > EOF
++
++  $ REQUEST_METHOD=GET hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++  $ hg bookmark -d bm
++  abort: bookmark 'bm' does not exist
++  [255]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/killdaemons.py"
++
++Attempting a write command with an unknown HTTP verb fails
++
++  $ REQUEST_METHOD=someverb hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++  $ hg bookmark -d bm
++  abort: bookmark 'bm' does not exist
++  [255]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  405 push requires POST request
++  
++  0
++  push requires POST request
++  [1]
++
++  $ "$TESTDIR/killdaemons.py"
++
++Pushing on a plaintext channel is disabled by default
++
++  $ cat > .hg/hgrc <<EOF
++  > EOF
++
++  $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 ssl required
++  
++  0
++  ssl required
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 ssl required
++  
++  0
++  ssl required
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  200 ssl required
++  
++  0
++  ssl required
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  200 ssl required
++  
++  0
++  ssl required
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  remote: ssl required
++  updating bookmark bm failed!
++  [1]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  remote: ssl required
++  remote: ssl required
++  updating cb9a9f314b8b to public failed!
++  [1]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_push=* denies pushing to unauthenticated users
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > deny_push = *
++  > EOF
++
++  $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_push=* denies pushing to authenticated users
++
++  $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_push=<user> denies pushing to user in list
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > deny_push = baduser
++  > EOF
++
++  $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_push=<user> denies pushing to user not in list because allow_push isn't set
++
++  $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_push=* allows pushes from unauthenticated users
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > allow_push = *
++  > EOF
++
++  $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 Script output follows
++  
++  1
++
++  $ hg bookmarks
++     bm                        0:cb9a9f314b8b
++  $ hg book -d bm
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  200 Script output follows
++  
++  write command no defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  200 Script output follows
++  
++  write command w/ defined permissions
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  [1]
++
++  $ hg book -d bm
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  remote: adding changesets
++  remote: adding manifests
++  remote: adding file changes
++  remote: added 1 changesets with 1 changes to 1 files
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_push=* allows pushes from authenticated users
++
++  $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 Script output follows
++  
++  1
++
++  $ hg bookmarks
++     bm                        0:cb9a9f314b8b
++  $ hg book -d bm
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  200 Script output follows
++  
++  write command no defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  200 Script output follows
++  
++  write command w/ defined permissions
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ cd ..
++  $ rm -rf test2
++  $ hg clone test test2
++  updating to branch default
++  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
++  $ cd test2
++  $ echo a >> a
++  $ hg ci -mb
++  $ hg book bm -r 0
++  $ cd ../test
++  $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  [1]
++
++  $ hg book -d bm
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  remote: adding changesets
++  remote: adding manifests
++  remote: adding file changes
++  remote: added 1 changesets with 1 changes to 1 files
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_push=<user> denies push to user not in list
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > allow_push = gooduser
++  > EOF
++
++  $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ cd ..
++  $ rm -rf test2
++  $ hg clone test test2
++  updating to branch default
++  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
++  $ cd test2
++  $ echo a >> a
++  $ hg ci -mb
++  $ hg book bm -r 0
++  $ cd ../test
++  $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_push=<user> allows push from user in list
++
++  $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 Script output follows
++  
++  1
++
++  $ hg bookmarks
++     bm                        0:cb9a9f314b8b
++  $ hg book -d bm
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  200 Script output follows
++  
++  1
++
++  $ hg bookmarks
++     bm                        0:cb9a9f314b8b
++  $ hg book -d bm
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  200 Script output follows
++  
++  write command no defined permissions
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  200 Script output follows
++  
++  write command w/ defined permissions
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ cd ..
++  $ rm -rf test2
++  $ hg clone test test2
++  updating to branch default
++  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
++  $ cd test2
++  $ echo a >> a
++  $ hg ci -mb
++  $ hg book bm -r 0
++  $ cd ../test
++  $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  [1]
++
++  $ hg book -d bm
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  remote: adding changesets
++  remote: adding manifests
++  remote: adding file changes
++  remote: added 1 changesets with 1 changes to 1 files
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.deny_push takes precedence over web.allow_push
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > allow_push = someuser
++  > deny_push = someuser
++  > EOF
++
++  $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritenoperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customwritewithperm'
++  401 push not authorized
++  
++  0
++  push not authorized
++  [1]
++
++Reset server to remove REQUEST_METHOD hack to test hg client
++
++  $ "$TESTDIR/killdaemons.py"
++  $ cd ..
++  $ rm -rf test2
++  $ hg clone test test2
++  updating to branch default
++  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
++  $ cd test2
++  $ echo a >> a
++  $ hg ci -mb
++  $ hg book bm -r 0
++  $ cd ../test
++  $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  no changes found
++  exporting bookmark bm
++  abort: authorization failed
++  [255]
++
++  $ hg --cwd ../test2 push http://localhost:$HGPORT/
++  pushing to http://localhost:$HGPORT/
++  searching for changes
++  abort: authorization failed
++  [255]
++
++  $ "$TESTDIR/killdaemons.py"
++
++web.allow_push has no effect if web.deny_read is set
++
++  $ cat > .hg/hgrc <<EOF
++  > [web]
++  > push_ssl = false
++  > allow_push = *
++  > deny_read = *
++  > EOF
++
++  $ REQUEST_METHOD=POST REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid
++  $ cat hg.pid > $DAEMON_PIDS
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
++
++  $ hg bookmarks
++  no bookmarks set
++
++  $ "$TESTDIR/get-with-headers.py" $LOCALIP:$HGPORT '?cmd=customreadnoperm'
++  401 read not authorized
++  
++  0
++  read not authorized
++  [1]
+diff -r cceaf7af4c9e tests/test-pull-http.t
+--- a/tests/test-pull-http.t	Sat Jun 01 17:09:41 2013 -0500
++++ b/tests/test-pull-http.t	Tue Jul 03 11:25:06 2018 +0200
+@@ -37,7 +37,6 @@
+   $ hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
+   $ cat hg.pid >> $DAEMON_PIDS
+   $ hg clone http://localhost:$HGPORT/ test4
+-  requesting all changes
+   abort: authorization failed
+   [255]
+   $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
+@@ -57,7 +56,6 @@
+ expect error, pulling not allowed
+ 
+   $ req
+-  pulling from http://localhost:$HGPORT/
+   abort: authorization failed
+   % serve errors
+ 
diff --git a/SOURCES/mercurial-cve-2018-13346-cve-2018-13347.patch b/SOURCES/mercurial-cve-2018-13346-cve-2018-13347.patch
new file mode 100644
index 0000000..a54175b
--- /dev/null
+++ b/SOURCES/mercurial-cve-2018-13346-cve-2018-13347.patch
@@ -0,0 +1,202 @@
+diff -ru mercurial-2.6.2/mercurial/mpatch.c mercurial-2.6.2_patched/mercurial/mpatch.c
+--- mercurial-2.6.2/mercurial/mpatch.c	2013-06-02 00:10:16.000000000 +0200
++++ mercurial-2.6.2_patched/mercurial/mpatch.c	2019-05-07 16:51:13.631774481 +0200
+@@ -74,6 +74,35 @@
+ 	return a->tail - a->head;
+ }
+ 
++/* add helper to add src and *dest iff it won't overflow */
++static inline int safeadd(int src, int *dest)
++{
++	if ((src > 0) == (*dest > 0)) {
++		if (*dest > 0) {
++			if (src > (INT_MAX - *dest)) {
++				return 0;
++			}
++		} else {
++			if (src < (INT_MIN - *dest)) {
++				return 0;
++			}
++		}
++	}
++	*dest += src;
++	return 1;
++}
++
++/* subtract src from dest and store result in dest */
++static inline int safesub(int src, int *dest)
++{
++	if (((src > 0) && (*dest < INT_MIN + src)) ||
++	    ((src < 0) && (*dest > INT_MAX + src))) {
++		return 0;
++	}
++	*dest -= src;
++	return 1;
++}
++
+ /* move hunks in source that are less cut to dest, compensating
+    for changes in offset. the last hunk may be split if necessary.
+ */
+@@ -83,18 +112,37 @@
+ 	int postend, c, l;
+ 
+ 	while (s != src->tail) {
+-		if (s->start + offset >= cut)
++		int soffset = s->start;
++		if (!safeadd(offset, &soffset))
++			break; /* add would overflow, oh well */
++		if (soffset >= cut)
+ 			break; /* we've gone far enough */
+ 
+-		postend = offset + s->start + s->len;
++		postend = offset;
++		if (!safeadd(s->start, &postend) ||
++		    !safeadd(s->len, &postend)) {
++			break;
++		}
+ 		if (postend <= cut) {
+ 			/* save this hunk */
+-			offset += s->start + s->len - s->end;
++			int tmp = s->start;
++			if (!safesub(s->end, &tmp)) {
++				break;
++			}
++			if (!safeadd(s->len, &tmp)) {
++				break;
++			}
++			if (!safeadd(tmp, &offset)) {
++				break; /* add would overflow, oh well */
++			}
+ 			*d++ = *s++;
+ 		}
+ 		else {
+ 			/* break up this hunk */
+-			c = cut - offset;
++			c = cut;
++			if (!safesub(offset, &c)) {
++				break;
++			}
+ 			if (s->end < c)
+ 				c = s->end;
+ 			l = cut - offset - s->start;
+@@ -128,16 +176,40 @@
+ 	int postend, c, l;
+ 
+ 	while (s != src->tail) {
+-		if (s->start + offset >= cut)
++		int cmpcut = s->start;
++		if (!safeadd(offset, &cmpcut)) {
++			break;
++		}
++		if (cmpcut >= cut)
+ 			break;
+ 
+-		postend = offset + s->start + s->len;
++		postend = offset;
++		if (!safeadd(s->start, &postend)) {
++			break;
++		}
++		if (!safeadd(s->len, &postend)) {
++			break;
++		}
+ 		if (postend <= cut) {
+-			offset += s->start + s->len - s->end;
++			/* do the subtraction first to avoid UB integer overflow
++			 */
++			int tmp = s->start;
++			if (!safesub(s->end, &tmp)) {
++				break;
++			}
++			if (!safeadd(s->len, &tmp)) {
++				break;
++			}
++			if (!safeadd(tmp, &offset)) {
++				break;
++			}
+ 			s++;
+ 		}
+ 		else {
+-			c = cut - offset;
++			c = cut;
++			if (!safesub(offset, &c)) {
++				break;
++			}
+ 			if (s->end < c)
+ 				c = s->end;
+ 			l = cut - offset - s->start;
+@@ -179,8 +251,18 @@
+ 
+ 			/* insert new hunk */
+ 			ct = c->tail;
+-			ct->start = bh->start - offset;
+-			ct->end = bh->end - post;
++			ct->start = bh->start;
++			ct->end = bh->end;
++			if (!safesub(offset, &(ct->start)) ||
++			    !safesub(post, &(ct->end))) {
++				/* It was already possible to exit
++				 * this function with a return value
++				 * of NULL before the safesub()s were
++				 * added, so this should be fine. */
++				lfree(c);
++				c = NULL;
++				goto done;
++			}
+ 			ct->len = bh->len;
+ 			ct->data = bh->data;
+ 			c->tail++;
+@@ -191,7 +273,7 @@
+ 		memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a));
+ 		c->tail += lsize(a);
+ 	}
+-
++done:
+ 	lfree(a);
+ 	lfree(b);
+ 	return c;
+@@ -215,13 +297,17 @@
+ 		lt->start = getbe32(bin);
+ 		lt->end = getbe32(bin + 4);
+ 		lt->len = getbe32(bin + 8);
+-		if (lt->start > lt->end)
+-			break; /* sanity check */
+-		bin = data + lt->len;
+-		if (bin < data)
++		if (lt->start < 0 || lt->start > lt->end || lt->len < 0)
++ 			break; /* sanity check */
++		bin = data;
++		if (!safeadd(lt->len, &bin)) {
+ 			break; /* big data + big (bogus) len can wrap around */
++		}
+ 		lt->data = data;
+-		data = bin + 12;
++		data = bin;
++		if (!safeadd(12, &data)) {
++			break;
++		}
+ 		lt++;
+ 	}
+ 
+@@ -266,7 +352,8 @@
+ 	char *p = buf;
+ 
+ 	while (f != l->tail) {
+-		if (f->start < last || f->end > len) {
++		if (f->start < last || f->start > len || f->end > len ||
++            last < 0) {
+ 			if (!PyErr_Occurred())
+ 				PyErr_SetString(mpatch_Error,
+ 				                "invalid patch");
+@@ -279,6 +366,12 @@
+ 		p += f->len;
+ 		f++;
+ 	}
++	if (last < 0) {
++		if (!PyErr_Occurred())
++			PyErr_SetString(mpatch_Error,
++			                "invalid patch");
++		return 0;
++	}
+ 	memcpy(p, orig + last, len - last);
+ 	return 1;
+ }
diff --git a/SPECS/mercurial.spec b/SPECS/mercurial.spec
index 8b727f2..3b32409 100644
--- a/SPECS/mercurial.spec
+++ b/SPECS/mercurial.spec
@@ -3,7 +3,7 @@
 Summary: Mercurial -- a distributed SCM
 Name: mercurial
 Version: 2.6.2
-Release: 8%{?dist}
+Release: 10%{?dist}
 #Release: 1.rc1%{?dist}
 
 #%define upstreamversion %{version}-rc
@@ -24,6 +24,8 @@ Patch3: mercurial-cve-2016-3068.patch
 Patch4: mercurial-cve-2016-3069.patch
 Patch5: mercurial-cve-2017-9462.patch
 Patch6: mercurial-cve-2017-1000115-1000116.patch
+Patch7: mercurial-cve-2018-1000132.patch
+Patch8: mercurial-cve-2018-13346-cve-2018-13347.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: python python-devel
@@ -99,6 +101,8 @@ documentation.
 %patch4 -p1
 %patch5 -p1
 %patch6 -p1
+%patch7 -p1
+%patch8 -p1
 
 %build
 make all
@@ -201,10 +205,18 @@ rm -rf $RPM_BUILD_ROOT
 %{_libexecdir}/mercurial/
 %{_sysconfdir}/mercurial/hgrc.d/hgk.rc
 
-##%%check
-##cd tests && %{__python} run-tests.py
+#%%check
+#cd tests && %%{__python} run-tests.py
 
 %changelog
+* Tue May 07 2019 Marcel Plch <mplch@redhat.com> - 2.6.2-10
+- Add missing hunk for CVE-2018-13347 patch
+- Related: CVE-2018-13347
+
+* Wed Mar 20 2019 Marcel Plch <mplch@redhat.com> - 2.6.2-9
+- Fix various CVE's
+- Resolves: CVE-2018-1000132 CVE-2018-13346 CVE-2018-13347
+
 * Tue Aug 15 2017 Petr Stodulka <pstodulk@redhat.com> - 2.6.2-8
 - Fix CVE-2017-1000115 and CVE-2017-1000116