Re: Re* [PATCH v7 1/1] sideband: highlight keywords in remote sideband output
- From
Jonathan Nieder <jrnieder@gmail.com>
- Date
- Aug 18, 2018, 06:09 UTC
- Message-ID
- <20180818060911.GC241538@aiede.svl.corp.google.com>
- In-Reply-To
- <xmqq8t54bzo4.fsf_-_@gitster-ct.c.googlers.com>
(-cc: my @google.com email) Hi,
Junio C Hamano wrote:
Show 15 quoted lines
> Subject: sideband: do not read beyond the end of input > > The caller of maybe_colorize_sideband() gives a counted buffer > <src,n>, but the callee checked *src as if it were a NUL terminated > buffer. If src[] had all isspace() bytes in it, we would have made > n negative, and then (1) called number of strncasecmp() to see if > the remaining bytes in src[] matched keywords, reading beyond the > end of the array, and/or (2) called strbuf_add() with negative > count, most likely triggering the "you want to use way too much > memory" error due to unsigned integer overflow. > > Signed-off-by: Junio C Hamano <gitster@pobox.com> > --- > sideband.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-)
This indeed avoids the "you want to use way too much memory" error when I apply it.
> --- a/sideband.c > +++ b/sideband.c > @@ -75,7 +75,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
Not about this patch: should the 'n' parameter be a size_t instead of an int? It doesn't matter in practice (since the caller has an int, it can never be more than INT_MAX) but it might make the intent clearer.
Based on inspecting the caller, using an int seems fine.
Show 5 quoted lines
> return;
> }
>
> - while (isspace(*src)) {
> + while (0 < n && isspace(*src)) {Yes, we need to check 'n && isspace(*src)' to avoid overflowing the buffer if it consists entirely of spaces.
Show 10 quoted lines
> strbuf_addch(dest, *src);
> src++;
> n--;
> @@ -84,6 +84,9 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
> for (i = 0; i < ARRAY_SIZE(keywords); i++) {
> struct keyword_entry *p = keywords + i;
> int len = strlen(p->keyword);
> +
> + if (n <= len)
> + continue;Using <= instead of < since we look at the character after the word as well. Good.
Show 7 quoted lines
> /*
> * Match case insensitively, so we colorize output from existing
> * servers regardless of the case that they use for their
> * messages. We only highlight the word precisely, so
> * "successful" stays uncolored.
> */
> if (!strncasecmp(p->keyword, src, len) && !isalnum(src[len])) {Not about this patch: should this check "&& src[len] == ':'" instead, as discussed upthread?
Show 7 quoted lines
> @@ -100,8 +103,8 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) > } > } > > - strbuf_add(dest, src, n); > + if (0 < n) > + strbuf_add(dest, src, n);
This check seems unnecessary. strbuf_add can cope fine with !n. Should we put
assert(n >= 0);
or even
if (n < 0) BUG();
instead, since the earlier part of the fix guarantees that n >= 0?
Thanks for the careful work. With or without such a change, Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Thanks.