diff options
author | Patrick Steinhardt <ps@pks.im> | 2016-11-01 16:56:07 +0100 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2016-11-02 09:41:39 +0100 |
commit | 61530c497dc23f6140557059ca9a55805c21b5fc (patch) | |
tree | 4e72babb1b20e416e26ca67409c08515badba6c9 | |
parent | 6502398f9643442f28a91ecad0a3695bb9ea5ec0 (diff) | |
download | libgit2-61530c497dc23f6140557059ca9a55805c21b5fc.tar.gz |
transports: smart: abort ref announcement on early end of stream
When reading a server's reference announcements via the smart
protocol, we expect the server to send multiple flushes before
the protocol is finished. If we fail to receive new data from the
socket, we will only return an end of stream error if we have not
seen any flush yet.
This logic is flawed in that we may run into an infinite loop
when receiving a server's reference announcement with a bogus
flush packet. E.g. assume the last flushing package is changed to
not be '0000' but instead any other value. In this case, we will
still await one more flush package and ignore the fact that we
are not receiving any data from the socket, causing an infinite
loop.
Fix the issue by always returning `GIT_EEOF` if the socket
indicates an end of stream.
-rw-r--r-- | src/transports/smart_protocol.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 3448fa7fb..5db4dda9a 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -50,7 +50,7 @@ int git_smart__store_refs(transport_smart *t, int flushes) if ((recvd = gitno_recv(buf)) < 0) return recvd; - if (recvd == 0 && !flush) { + if (recvd == 0) { giterr_set(GITERR_NET, "early EOF"); return GIT_EEOF; } |