Commit 61530c497dc23f6140557059ca9a55805c21b5fc

Patrick Steinhardt 2016-11-01T16:56:07

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 3448fa7..5db4dda 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;
 			}