# HG changeset patch # User Martin von Zweigbergk # Date 1553496421 25200 # Node ID caa067ee21dcb816395687d127ca5f2a83ce3110 # Parent 27475ae67676f68e20f0b18e7d6634ee6dd2d282 changelog: extract a _string_unescape() to mirror _string_escape() We use our own _string_escape() to encode the "extras" field. Then we use codecs.escape_decode() to escape it. But there's also a little workaround for dealing with escaped text that looks like octal numbers since the fix for https://bz.mercurial-scm.org/show_bug.cgi?id=3156. This patch extracts the call to codecs.escape_decode() along with the fix for octal numbers and puts it in a _string_unescape(). It also updates the test to check for the octal-number case from the aforementioned bug. As you may have suspected, I want to be able to reuse this new function later. Differential Revision: https://phab.mercurial-scm.org/D6184 diff -r 27475ae67676 -r caa067ee21dc mercurial/changelog.py --- a/mercurial/changelog.py Wed Mar 20 11:42:02 2019 -0700 +++ b/mercurial/changelog.py Sun Mar 24 23:47:01 2019 -0700 @@ -35,17 +35,25 @@ """ >>> from .pycompat import bytechr as chr >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)} - >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d + >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)s12ab%(cr)scd%(bs)s%(nl)s" % d >>> s - 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n' + 'ab\\ncd\\\\\\\\n\\x0012ab\\rcd\\\\\\n' >>> res = _string_escape(s) - >>> s == stringutil.unescapestr(res) + >>> s == _string_unescape(res) True """ # subset of the string_escape codec text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r') return text.replace('\0', '\\0') +def _string_unescape(text): + if '\\0' in text: + # fix up \0 without getting into trouble with \\0 + text = text.replace('\\\\', '\\\\\n') + text = text.replace('\\0', '\0') + text = text.replace('\n', '') + return stringutil.unescapestr(text) + def decodeextra(text): """ >>> from .pycompat import bytechr as chr @@ -60,12 +68,7 @@ extra = _defaultextra.copy() for l in text.split('\0'): if l: - if '\\0' in l: - # fix up \0 without getting into trouble with \\0 - l = l.replace('\\\\', '\\\\\n') - l = l.replace('\\0', '\0') - l = l.replace('\n', '') - k, v = stringutil.unescapestr(l).split(':', 1) + k, v = _string_unescape(l).split(':', 1) extra[k] = v return extra