pkt-line: prepare buffer before handling ERR packets
authorJeff King <peff@peff.net>
Sat, 13 Apr 2019 05:54:02 +0000 (01:54 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Apr 2019 05:00:51 +0000 (14:00 +0900)
Since 2d103c31c2 (pack-protocol.txt: accept error packets in any
context, 2018-12-29), the pktline code will detect an ERR packet and die
automatically, saving the caller from dealing with it. But we do so too
early in the function, before we have terminated the buffer with a NUL.

As a result, passing the ERR message to die() may result in us printing
random cruft from a previous packet. This doesn't trigger memory tools
like ASan because we reuse the same buffer over and over (so the
contents are valid and initialized; they're just stale).

We can see demonstrate this by tightening the regex we use to match the
error message in t5516; without this patch, git-fetch will accidentally
print the capabilities from the (much longer) initial packet we
received.

By moving the ERR code later in the function we get a few other
benefits, too:

- we'll now chomp any newline sent by the other side (which is what we
want, since die() will add its own newline)

- we'll now mention the ERR packet with GIT_TRACE_PACKET

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pkt-line.c
t/t5516-fetch-push.sh
index ffd722054489e6ea837bb417578afd085cebb467..c9ed780d0be02aa111786d500cd4eea2cc7ccd25 100644 (file)
@@ -350,16 +350,17 @@ enum packet_read_status packet_read_with_status(int fd, char **src_buffer,
                return PACKET_READ_EOF;
        }
 
-       if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
-           starts_with(buffer, "ERR "))
-               die(_("remote error: %s"), buffer + 4);
-
        if ((options & PACKET_READ_CHOMP_NEWLINE) &&
            len && buffer[len-1] == '\n')
                len--;
 
        buffer[len] = 0;
        packet_trace(buffer, len, 0);
+
+       if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
+           starts_with(buffer, "ERR "))
+               die(_("remote error: %s"), buffer + 4);
+
        *pktlen = len;
        return PACKET_READ_NORMAL;
 }
index 747dc4c31d062b8efb6ac3a0f894c0ee060742bc..98ef71b48c9b70a1cdf72b571e4bee8eea3e5723 100755 (executable)
@@ -1241,7 +1241,7 @@ do
                        git fetch ../testrepo/.git $SHA1_2 &&
                        git cat-file commit $SHA1_2 &&
                        test_must_fail git fetch ../testrepo/.git $SHA1_3 2>err &&
-                       test_i18ngrep "remote error:.*not our ref" err
+                       test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
                )
        '
 done