Commit 786426ea6ec2a76ffe2515dc5182705fb3d44603

Patrick Steinhardt 2018-08-09T10:46:58

smart_pkt: check whether error packets are prefixed with "ERR " In the `git_pkt_parse_line` function, we determine what kind of packet a given packet line contains by simply checking for the prefix of that line. Except for "ERR" packets, we always only check for the immediate identifier without the trailing space (e.g. we check for an "ACK" prefix, not for "ACK "). But for "ERR" packets, we do in fact include the trailing space in our check. This is not really much of a problem at all, but it is inconsistent with all the other packet types and thus causes confusion when the `err_pkt` function just immediately skips the space without checking whether it overflows the line buffer. Adjust the check in `git_pkt_parse_line` to not include the trailing space and instead move it into `err_pkt` for consistency.

diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index c6cc65e..99414da 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -107,10 +107,12 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len)
 
 static int err_pkt(git_pkt **out, const char *line, size_t len)
 {
-	git_pkt_err *pkt;
+	git_pkt_err *pkt = NULL;
 	size_t alloclen;
 
 	/* Remove "ERR " from the line */
+	if (git__prefixncmp(line, len, "ERR "))
+		goto out_err;
 	line += 4;
 	len -= 4;
 
@@ -127,6 +129,11 @@ static int err_pkt(git_pkt **out, const char *line, size_t len)
 	*out = (git_pkt *) pkt;
 
 	return 0;
+
+out_err:
+	giterr_set(GITERR_NET, "error parsing ERR pkt-line");
+	git__free(pkt);
+	return -1;
 }
 
 static int data_pkt(git_pkt **out, const char *line, size_t len)
@@ -463,7 +470,7 @@ int git_pkt_parse_line(
 		ret = ack_pkt(head, line, len);
 	else if (!git__prefixncmp(line, len, "NAK"))
 		ret = nak_pkt(head);
-	else if (!git__prefixncmp(line, len, "ERR "))
+	else if (!git__prefixncmp(line, len, "ERR"))
 		ret = err_pkt(head, line, len);
 	else if (*line == '#')
 		ret = comment_pkt(head, line, len);