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

Re: [PATCH] t5500.43: make the check a bit more robust

From
Jeff King <peff@peff.net>
Date
Oct 13, 2020, 19:09 UTC
Message-ID
<20201013190913.GB2994107@coredump.intra.peff.net>
In-Reply-To
<20201013185515.GA2994107@coredump.intra.peff.net>
On Tue, Oct 13, 2020 at 02:55:15PM -0400, Jeff King wrote:
Show 8 quoted lines
> But then in fbd76cd450 (sideband: reverse its dependency on pkt-line,
> 2019-01-16), the function became demultiplex_sideband(). The loop went
> away, and we pump only a single packet on each call. When we see
> sideband 2, we do an early return. But on sideband 1, we continue to the
> cleanup: label, which flushes the scratch buffer.
> 
> I think we need to return from there without hitting that cleanup label,
> like this:

By the way, the reason this works is that the "scratch" buffer persists beyond individual calls to demultiplex_sideband(). So we can get away with letting it persist between the two.

However unlike the original recv_sideband(), which broke out of the loop on error and then flushed scratch, our post-fbd76cd450 does not do the same. It now looks like:

int recv_sideband(const char *me, int in_stream, int out)
{
        char buf[LARGE_PACKET_MAX + 1];
        int len;
        struct strbuf scratch = STRBUF_INIT;
        enum sideband_type sideband_type;
        while (1) {
                len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX,
                                  0);
                if (!demultiplex_sideband(me, buf, len, 0, &scratch,
                                          &sideband_type))
                        continue;
                switch (sideband_type) {
                case SIDEBAND_PRIMARY:
                        write_or_die(out, buf + 1, len - 1);
                        break;
                default: /* errors: message already written */
                        return sideband_type;
                }
        }
}

I wondered if we could ever have a case where we broke out of the loop with data left over in "scratch" (or its buffer left allocated). I think the answer is no. We only break out of the loop if demultiplex_sideband() returned non-zero _and_ its not the primary sideband. So both before and after my suggested fix, we'd have hit the cleanup label in demultiplex_sideband(), which flushes and frees the buffer.

I do have to say that the original loop before that commit was a lot easier to follow, though.

Another weirdness I noticed is that it doesn't distinguish a flush packet (expected) from a zero-byte packet (an error). But neither did the original. I would have guessed the zero-byte packet was meant to trigger this second conditional:

        if (len == 0) {
                *sideband_type = SIDEBAND_FLUSH;
                goto cleanup;
        }
        if (len < 1) {
                strbuf_addf(scratch,
                            "%s%s: protocol error: no band designator",
                            scratch->len ? "\n" : "", me);
                *sideband_type = SIDEBAND_PROTOCOL_ERROR;
                goto cleanup;
        }

but we'd hit the first conditional before then. We would still trigger the second if we saw EOF while reading the packet (because we set the length to -1 then), but then it's arguably the wrong error to be showing.

So I think this could be improved a bit by using packet_read_with_status() in the recv_sideband() caller.

-Peff
Previous: Junio C HamanoNext: Johannes Schindelin
Message 5 of 33 in “t5500.43: make the check a bit more robust”
  1. t5500.43: make the check a bit more robustJohannes Schindelin via GitGitGadget, Oct 13, 2020
  2. Junio C HamanoOct 13, 2020
  3. Jeff KingOct 13, 2020
  4. Junio C HamanoOct 13, 2020
  5. Jeff KingOct 13, 2020
  6. Johannes SchindelinOct 17, 2020
  7. Johannes SchindelinOct 17, 2020
  8. 0/3 Work around flakiness in t5500.43Johannes Schindelin via GitGitGadget, Oct 19, 2020
  9. 1/3 sideband: avoid reporting incomplete sideband messagesJohannes Schindelin via GitGitGadget, Oct 19, 2020
  10. Junio C HamanoOct 20, 2020
  11. Johannes SchindelinOct 20, 2020
  12. Junio C HamanoOct 20, 2020
  13. 2/3 sideband: report unhandled incomplete sideband messages as bugsJohannes Schindelin via GitGitGadget, Oct 19, 2020
  14. 3/3 sideband: add defense against packets missing a band designatorJohannes Schindelin via GitGitGadget, Oct 19, 2020
  15. Junio C HamanoOct 20, 2020
  16. Jeff KingOct 23, 2020
  17. Junio C HamanoOct 23, 2020
  18. Jeff KingOct 23, 2020
  19. Johannes SchindelinOct 23, 2020
  20. Jeff KingOct 23, 2020
  21. Johannes SchindelinOct 26, 2020
  22. 0/2 Work around flakiness in t5500.43Johannes Schindelin via GitGitGadget, Oct 26, 2020
  23. 1/2 sideband: avoid reporting incomplete sideband messagesJohannes Schindelin via GitGitGadget, Oct 26, 2020
  24. 2/2 sideband: report unhandled incomplete sideband messages as bugsJohannes Schindelin via GitGitGadget, Oct 26, 2020
  25. Junio C HamanoOct 26, 2020
  26. sideband: diagnose more incoming packet anomaliesJeff King, Oct 27, 2020
  27. Jeff KingOct 27, 2020
  28. Junio C HamanoOct 27, 2020
  29. Jeff KingOct 27, 2020
  30. Junio C HamanoOct 27, 2020
  31. Jeff KingOct 28, 2020
  32. Jeff KingOct 27, 2020
  33. Junio C HamanoOct 27, 2020

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.