From 6502398f9643442f28a91ecad0a3695bb9ea5ec0 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 1 Nov 2016 16:55:16 +0100 Subject: [PATCH 1/3] proxy: fix typo in documentation --- include/git2/proxy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/proxy.h b/include/git2/proxy.h index dcd615633..194cbb651 100644 --- a/include/git2/proxy.h +++ b/include/git2/proxy.h @@ -19,7 +19,7 @@ typedef enum { /** * Do not attempt to connect through a proxy * - * If built against lbicurl, it itself may attempt to connect + * If built against libcurl, it itself may attempt to connect * to a proxy if the environment variables specify it. */ GIT_PROXY_NONE, From 61530c497dc23f6140557059ca9a55805c21b5fc Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 1 Nov 2016 16:56:07 +0100 Subject: [PATCH 2/3] 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. --- src/transports/smart_protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From 62494bf234919e04a6e145d59942d2a05c96ae0d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 2 Nov 2016 09:38:40 +0100 Subject: [PATCH 3/3] transports: smart: abort receiving packets on end of stream When trying to receive packets from the remote, we loop until either an error distinct to `GIT_EBUFS` occurs or until we successfully parsed the packet. This does not honor the case where we are looping over an already closed socket which has no more data, leaving us in an infinite loop if we got a bogus packet size or if the remote hang up. Fix the issue by returning `GIT_EEOF` when we cannot read data from the socket anymore. --- src/transports/smart_protocol.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 5db4dda9a..c1e412436 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -222,8 +222,12 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf) if (error < 0 && error != GIT_EBUFS) return error; - if ((ret = gitno_recv(buf)) < 0) + if ((ret = gitno_recv(buf)) < 0) { return ret; + } else if (ret == 0) { + giterr_set(GITERR_NET, "early EOF"); + return GIT_EEOF; + } } while (error); gitno_consume(buf, line_end);