Re: [PATCH 1/3] sideband: mask control characters
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Dec 2, 2025, 15:43 UTC
- Message-ID
- <7fa83a64-95f3-9ca8-537e-12a7f919d8ae@gmx.de>
- In-Reply-To
- <f2ce08c4-f70e-487a-8dd9-286ee5bc683d@gmail.com>
Hi Phillip,
On Wed, 15 Jan 2025, Phillip Wood wrote:
Show 13 quoted lines
> Just a couple of small comments
>
> On 14/01/2025 18:19, Johannes Schindelin via GitGitGadget wrote:
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > +static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int
> > n)
> > +{
> > + strbuf_grow(dest, n);
> > + for (; n && *src; src++, n--) {
> > + if (!iscntrl(*src) || *src == '\t' || *src == '\n')
>
> Isn't it a bug to pass '\n' to maybe_colorize_sideband() ?While a band 2 message is indeed split by newlines and fed to this function line by line, which is the case for a long time already: since ed1902ef5c6 (cope with multiple line breaks within sideband progress messages, 2007-10-16), the same is not true for band 3 messages: They pass the entire message in one go (and for multi-line payload, only the first line is prefixed with `remote:`, which is arguably a bug, but not one that is within this here patch series' scope).
See https://gitlab.com/git-scm/git/-/blob/v2.52.0/sideband.c#L191 and https://gitlab.com/git-scm/git/-/blob/v2.52.0/sideband.c#L176, respectively.
So no, I don't think that we can currently consider it a bug to pass `\n` as part of the `src` parameter to `maybe_colorize_sideband()`.
Show 7 quoted lines
> > + strbuf_addch(dest, *src);
> > + else {
> > + strbuf_addch(dest, '^');
> > + strbuf_addch(dest, 0x40 + *src);
>
> This will escape DEL ('\x7f') as "^\xbf" which is invalid in utf-8 locales.
> Perhaps we could use "^?" for that instead.Good point! This seems to be the historical way to escape DEL, probably because 0x3f ('?') is 0x7f + 0x40 truncated to 7 bits. I'll do this in the next iteration:
-- snip --
diff --git a/sideband.c b/sideband.c index f613d4d6cc3..684621579fd 100644 --- a/sideband.c +++ b/sideband.c @@ -175,7 +175,7 @@ static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n) n -= i; } else { strbuf_addch(dest, '^'); - strbuf_addch(dest, 0x40 + *src); + strbuf_addch(dest, *src == 0x7f ? '?' : 0x40 + *src); } } } -- snap -- > > > +test_expect_success 'disallow (color) control sequences in sideband' ' > > + write_script .git/color-me-surprised <<-\EOF && > > + printf "error: Have you \\033[31mread\\033[m this?\\n" >&2 > > + exec "$@" > > + EOF > > + test_config_global uploadPack.packObjectshook ./color-me-surprised && > > + test_commit need-at-least-one-commit && > > + git clone --no-local . throw-away 2>stderr && > > + test_decode_color <stderr >decoded && > > + test_grep ! RED decoded > > I'd be happier if we used test_cmp() here so that we check that the sanitized > version matches what we expect and the test does not pass if there a typo in > the script above stops it from writing the SGR code for red. I often debug test failures in Git's test suite and one of the most annoying category of test failures is when test cases expect byte-wise exact Git output that changed for totally legitimate reasons [*1*]. Even worse: In many of those instances, the _intent_ of the check is not even clear from that `test_cmp` and has to be reconstructed, a boring, tedious task with little benefit to show for the effort. I much prefer tests like this one, where a precise `test_grep` states exactly what it expects to be present, or missing. The intent of such a command is much clearer than that of `test_cmp expect actual`. So, much as I appreciate your suggestion, I would prefer to keep the code as-is. Ciao, Johannes Footnote *1*: This really is not hypothetical. I had to battle quite a bit with unstable compression sizes that are part of a `test_cmp` comparison, https://github.com/git-for-windows/git/pull/5926#issuecomment-3486556940 shows a bit of the problems but is very shy about providing the specific number of days I spent on addressing this issue. In hindsight, I should have spent at most two hours on converting that from a byte-wise comparison to a qualitative comparison.