git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 1/3] strbuf: fix incorrect alloc size in strbuf_reencode()

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 17, 2026, 20:51 UTC
Message-ID
<xmqqseaz9jrd.fsf@gitster.g>
In-Reply-To
<821043c664e41d8e395e944df3ada8f697a69d0b.1771326521.git.gitgitgadget@gmail.com>

"Vaidas Pilkauskas via GitGitGadget" <gitgitgadget@gmail.com> writes:

Show 18 quoted lines
> From: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
>
> The strbuf_reencode() function incorrectly passes the string length
> as the allocation size to strbuf_attach(), when it should pass
> length + 1 to account for the null terminator.
>
> The reencode_string_len() function allocates len + 1 bytes (including
> the null terminator) and returns the string length (excluding the null
> terminator) via the len parameter. However, strbuf_reencode() then
> calls strbuf_attach() with this length value as both the len and alloc
> parameters:
>
>     strbuf_attach(sb, out, len, len);
>
> This is incorrect because strbuf_attach()'s alloc parameter should
> reflect the actual allocated buffer size, which includes space for the
> null terminator. This could lead to incorrect memory management in code
> that relies on sb->alloc being accurate.

I do agree that setting the correct number to .alloc member is a good thing to do, but I am afraid that the above characterization of a potential problem is incorrect.

If we were to extend the resulting strbuf further (by e.g., appending to it), we might end up reallocating the buffer a bit prematurely by one byte before it actually fills up, but the reallocation would be done by giving the piece of memory pointed at by "out" here to realloc(3), so the wrong value of "alloc" would not lead to incorrect memory management at all.

Upon further inspection, we see something else interesting. The strbuf_attach() function, immediately after initializing sb with the new values of buf/len/alloc, calls strbuf_grow(sb, 0) and triggers the ALLOC_GROW() growth thanks to this under specification. By the time the control returns to the caller, the sb->alloc would be (((len)+16)*3/2), not (len+1), and it records the actual allocation size. So there is no "could lead to incorrect memory management" at all, but this incorrect number forces us to always reallocate immediately after the strbuf_attach() call, which is a waste when we are not going to further extend the strbuf returned by this function.

And that is a very good reason to make this fix worth doing.
> Fix by passing len + 1 as the alloc parameter:
>
>     strbuf_attach(sb, out, len, len + 1);

I wonder how widespread this off-by-one error is. Shouldn't strbuf_attach() be doing some sanity checking of its parameters?

        void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
        {
                strbuf_release(sb);
                sb->buf   = buf;
                sb->len   = len;
                sb->alloc = alloc;
                strbuf_grow(sb, 0);
                sb->buf[sb->len] = '\0';
        }

Given the above code, it is clear that alloc must be at least as big as (len + 1), and the strbuf_grow(sb, 0) in between is papering over problems (at least it is doing so here for the caller you corrected).

Perhaps we want to replace the call to strbuf_grow(sb, 0) with something like

		if (alloc <= len)
			BUG("alloc must be larger than len");

instead? The log message of 917c9a71 (New strbuf APIs: splice and attach., 2007-09-15) is worth reading, but it is an iffy logic that depends too much (at least for my taste) on what strbuf_grow(sb, 0) actually does ;-).

Show 17 quoted lines
> Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
> ---
>  strbuf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/strbuf.c b/strbuf.c
> index 3939863cf3..3e04addc22 100644
> --- a/strbuf.c
> +++ b/strbuf.c
> @@ -168,7 +168,7 @@ int strbuf_reencode(struct strbuf *sb, const char *from, const char *to)
>  	if (!out)
>  		return -1;
>  
> -	strbuf_attach(sb, out, len, len);
> +	strbuf_attach(sb, out, len, len + 1);
>  	return 0;
>  }
Previous: Vaidas Pilkauskas via GitGitGadgetNext: Vaidas Pilkauskas
Message 19 of 49 in “http: add support for HTTP 429 rate limit retries”
  1. 0/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Nov 26, 2025
  2. 1/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Nov 26, 2025
  3. Taylor BlauDec 9, 2025
  4. Vaidas PilkauskasDec 12, 2025
  5. 2/3 remote-curl: fix memory leak in show_http_message()Vaidas Pilkauskas via GitGitGadget, Nov 26, 2025
  6. Taylor BlauDec 9, 2025
  7. 3/3 http: add trace2 logging for retry operationsVaidas Pilkauskas via GitGitGadget, Nov 26, 2025
  8. 0/2 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Dec 18, 2025
  9. 1/2 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Dec 18, 2025
  10. Taylor BlauFeb 11, 2026
  11. Jeff KingFeb 11, 2026
  12. Vaidas PilkauskasFeb 13, 2026
  13. Jeff KingFeb 15, 2026
  14. Vaidas PilkauskasFeb 13, 2026
  15. 2/2 http: add trace2 logging for retry operationsVaidas Pilkauskas via GitGitGadget, Dec 18, 2025
  16. Taylor BlauFeb 11, 2026
  17. 0/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 17, 2026
  18. 1/3 strbuf: fix incorrect alloc size in strbuf_reencode()Vaidas Pilkauskas via GitGitGadget, Feb 17, 2026
  19. Junio C HamanoFeb 17, 2026
  20. Vaidas PilkauskasFeb 18, 2026
  21. 2/3 remote-curl: introduce show_http_message_fatal() helperVaidas Pilkauskas via GitGitGadget, Feb 17, 2026
  22. 3/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 17, 2026
  23. 0/5 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  24. 1/5 strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()Vaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  25. 2/5 strbuf_attach: fix all call sites to pass correct allocVaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  26. Junio C HamanoFeb 20, 2026
  27. Vaidas PilkauskasFeb 23, 2026
  28. 3/5 strbuf: replace strbuf_grow() in strbuf_attach() with BUG() checkVaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  29. 4/5 remote-curl: introduce show_http_message_fatal() helperVaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  30. 5/5 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 18, 2026
  31. 0/4 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 23, 2026
  32. 1/4 strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()Vaidas Pilkauskas via GitGitGadget, Feb 23, 2026
  33. 2/4 strbuf_attach: fix call sites to pass correct allocVaidas Pilkauskas via GitGitGadget, Feb 23, 2026
  34. 3/4 remote-curl: introduce show_http_message_fatal() helperVaidas Pilkauskas via GitGitGadget, Feb 23, 2026
  35. Jeff KingMar 10, 2026
  36. 4/4 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Feb 23, 2026
  37. Jeff KingMar 10, 2026
  38. Junio C HamanoFeb 24, 2026
  39. Junio C HamanoMar 9, 2026
  40. Jeff KingMar 10, 2026
  41. Junio C HamanoMar 10, 2026
  42. 0/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Mar 17, 2026
  43. 2/3 strbuf_attach: fix call sites to pass correct allocVaidas Pilkauskas via GitGitGadget, Mar 17, 2026
  44. 3/3 http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas via GitGitGadget, Mar 17, 2026
  45. Taylor BlauMar 21, 2026
  46. 1/3 strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()Vaidas Pilkauskas via GitGitGadget, Mar 17, 2026
  47. Taylor BlauMar 21, 2026
  48. Junio C HamanoMar 21, 2026
  49. Vaidas PilkauskasMar 23, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.