[PATCH 7 of 7] client: handle commit messages with \0 characters for all commands
Augie Fackler
raf at durin42.com
Fri Mar 17 01:10:34 UTC 2023
Series LGTM, please feel encouraged to queue.
(I’m probably not a great reviewer for hglib at this point either, should we formally hand it over to someone else?)
> On Mar 14, 2023, at 04:26, Mathias De Mare <mathias.de_mare at nokia.com> wrote:
>
> # HG changeset patch
> # User Mathias De Mare <mathias.de_mare at nokia.com>
> # Date 1678717940 -3600
> # Mon Mar 13 15:32:20 2023 +0100
> # Node ID c2482b94ad1f644612d7e063e84d6f56b0d3b773
> # Parent c1d60b0bf6f30b40fac5084132f0c0d266dfae82
> client: handle commit messages with \0 characters for all commands
>
> Each of the impacted commands will now use the 'json' template,
> which they all support as of Mercurial 3.7.3 (the first version
> tested in the regression tests).
>
> Note: I tried to add a test with null bytes,
> but both hglib and using hg directly through subprocess
> rejected adding a commit message with a null byte.
>
> diff --git a/hglib/client.py b/hglib/client.py
> --- a/hglib/client.py
> +++ b/hglib/client.py
> @@ -159,20 +159,6 @@ class hgclient(object):
> return channel, self.server.stdout.read(length)
>
> @staticmethod
> - def _parserevs(splitted):
> - '''splitted is a list of fields according to our rev.style, where
> - each 6 fields compose one revision.
> - '''
> - revs = []
> - for rev in util.grouper(7, splitted):
> - # truncate the timezone and convert to a local datetime
> - posixtime = float(rev[6].split(b('.'), 1)[0])
> - dt = datetime.datetime.fromtimestamp(posixtime)
> - revs.append(revision(rev[0], rev[1], rev[2], rev[3],
> - rev[4], rev[5], dt))
> - return revs
> -
> - @staticmethod
> def _parsejsonrevs(jsonrevs):
> revs = []
> for rev in jsonrevs:
> @@ -929,7 +915,7 @@ class hgclient(object):
> rev = [rev]
>
> args = cmdbuilder(b('heads'), r=startrev, t=topological, c=closed,
> - template=templates.changeset, hidden=self.hidden,
> + template="json", hidden=self.hidden,
> *rev)
>
> def eh(ret, out, err):
> @@ -937,8 +923,12 @@ class hgclient(object):
> raise error.CommandError(args, ret, out, err)
> return b('')
>
> - out = self.rawcommand(args, eh=eh).split(b('\0'))[:-1]
> - return self._parserevs(out)
> + out = self.rawcommand(args, eh=eh)
> + if not out:
> + return []
> + json_out = json.loads(out)
> +
> + return self._parsejsonrevs(json_out)
>
> def identify(self, rev=None, source=None, num=False, id=False, branch=False,
> tags=False, bookmarks=False):
> @@ -1036,7 +1026,7 @@ class hgclient(object):
>
> """
> args = cmdbuilder(b('incoming'), path,
> - template=templates.changeset, r=revrange,
> + template="json", r=revrange,
> f=force, n=newest, bundle=bundle,
> B=bookmarks, b=branch, l=limit, M=nomerges,
> S=subrepos)
> @@ -1050,14 +1040,15 @@ class hgclient(object):
> return []
>
> out = util.eatlines(out, 2)
> +
> if bookmarks:
> bms = []
> for line in out.splitlines():
> bms.append(tuple(line.split()))
> return bms
> else:
> - out = out.split(b('\0'))[:-1]
> - return self._parserevs(out)
> + json_out = json.loads(out)
> + return self._parsejsonrevs(json_out)
>
> def log(self, revrange=None, files=[], follow=False,
> followfirst=False, date=None, copies=False, keyword=None,
> @@ -1235,7 +1226,7 @@ class hgclient(object):
> """
> args = cmdbuilder(b('outgoing'),
> path,
> - template=templates.changeset, r=revrange,
> + template="json", r=revrange,
> f=force, n=newest, B=bookmarks,
> b=branch, S=subrepos)
>
> @@ -1254,8 +1245,8 @@ class hgclient(object):
> bms.append(tuple(line.split()))
> return bms
> else:
> - out = out.split(b('\0'))[:-1]
> - return self._parserevs(out)
> + json_out = json.loads(out)
> + return self._parsejsonrevs(json_out)
>
> def parents(self, rev=None, file=None):
> """Return the working directory's parent revisions. If rev is given,
> @@ -1265,16 +1256,19 @@ class hgclient(object):
> is returned.
>
> """
> - args = cmdbuilder(b('parents'), file, template=templates.changeset,
> + args = cmdbuilder(b('parents'), file, template="json",
> r=rev, hidden=self.hidden)
>
> out = self.rawcommand(args)
> if not out:
> return
>
> - out = out.split(b('\0'))[:-1]
> + json_out = json.loads(out)
>
> - return self._parserevs(out)
> + if not json_out:
> + return
> +
> + return self._parsejsonrevs(json_out)
>
> def paths(self, name=None):
> """
> @@ -1682,12 +1676,12 @@ class hgclient(object):
> changeset most recently added to the repository (and therefore the most
> recently changed head).
> """
> - args = cmdbuilder(b('tip'), template=templates.changeset,
> + args = cmdbuilder(b('tip'), template="json",
> hidden=self.hidden)
> out = self.rawcommand(args)
> - out = out.split(b('\0'))
> + json_out = json.loads(out)
>
> - return self._parserevs(out)[0]
> + return self._parsejsonrevs(json_out)[0]
>
> def update(self, rev=None, clean=False, check=False, date=None):
> """
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at lists.mercurial-scm.org
> https://lists.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list