wireproto: unescape argument names in batch command (BC)
authorGregory Szorc <gregory.szorc@gmail.com>
Sat, 06 Aug 2016 13:55:21 -0700
changeset 29734 62e2e048d068
parent 29733 bb04f96df51c
child 29735 919a4b7f531d
wireproto: unescape argument names in batch command (BC) Clients escape both argument names and values when using the batch command. Yet the server was only unescaping argument values. Fortunately we don't have any argument names that need escaped. But that isn't an excuse to lack symmetry in the code. Since the server wasn't properly unescaping argument names, this means we can never introduce an argument to a batchable command that needs escaped because an old server wouldn't properly decode its name. So we've introduced an assertion to detect the accidental introduction of this in the future. Of course, we could introduce a server capability that says the server knows how to decode argument names and allow special argument names to go through. But until there is a need for it (which I doubt there will be), we shouldn't bother with adding an unused capability.
mercurial/wireproto.py
--- a/mercurial/wireproto.py	Sat Aug 06 13:46:28 2016 -0700
+++ b/mercurial/wireproto.py	Sat Aug 06 13:55:21 2016 -0700
@@ -191,6 +191,11 @@
     """Return a ``cmds`` argument value for the ``batch`` command."""
     cmds = []
     for op, argsdict in req:
+        # Old servers didn't properly unescape argument names. So prevent
+        # the sending of argument names that may not be decoded properly by
+        # servers.
+        assert all(escapearg(k) == k for k in argsdict)
+
         args = ','.join('%s=%s' % (escapearg(k), escapearg(v))
                         for k, v in argsdict.iteritems())
         cmds.append('%s %s' % (op, args))
@@ -620,7 +625,7 @@
         for a in args.split(','):
             if a:
                 n, v = a.split('=')
-                vals[n] = unescapearg(v)
+                vals[unescapearg(n)] = unescapearg(v)
         func, spec = commands[op]
         if spec:
             keys = spec.split()