git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 03/11] pkt-line: create gentle packet_read_line functions

From
KWKevin Wern <kevin.m.wern@gmail.com>
Date
Sep 16, 2016, 00:12 UTC
Message-ID
<1473984742-12516-4-git-send-email-kevin.m.wern@gmail.com>
In-Reply-To
<1473984742-12516-1-git-send-email-kevin.m.wern@gmail.com>

Create a functions that can read malformed messages without dying. Includes creation of flag PACKET_READ_GENTLE_ALL. For use handling prime-clone (or other server error) responses.

Signed-off-by: Kevin Wern <kevin.m.wern@gmail.com>
---
 pkt-line.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 pkt-line.h | 16 ++++++++++++++++
 2 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/pkt-line.c b/pkt-line.c
index 62fdb37..96060e5 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -155,13 +155,17 @@ static int get_packet_data(int fd, char **src_buf, size_t *src_size,
 		*src_size -= ret;
 	} else {
 		ret = read_in_full(fd, dst, size);
-		if (ret < 0)
+		if (ret < 0) {
+			if (options & PACKET_READ_GENTLE_ALL)
+				return -1;
+
 			die_errno("read error");
+		}
 	}
 
 	/* And complain if we didn't get enough bytes to satisfy the read. */
 	if (ret < size) {
-		if (options & PACKET_READ_GENTLE_ON_EOF)
+		if (options & (PACKET_READ_GENTLE_ON_EOF | PACKET_READ_GENTLE_ALL))
 			return -1;
 
 		die("The remote end hung up unexpectedly");
@@ -205,15 +209,23 @@ int packet_read(int fd, char **src_buf, size_t *src_len,
 	if (ret < 0)
 		return ret;
 	len = packet_length(linelen);
-	if (len < 0)
+	if (len < 0) {
+		if (options & PACKET_READ_GENTLE_ALL)
+			return -1;
+
 		die("protocol error: bad line length character: %.4s", linelen);
+	}
 	if (!len) {
 		packet_trace("0000", 4, 0);
 		return 0;
 	}
 	len -= 4;
-	if (len >= size)
+	if (len >= size) {
+		if (options & PACKET_READ_GENTLE_ALL)
+			return -1;
+
 		die("protocol error: bad line length %d", len);
+	}
 	ret = get_packet_data(fd, src_buf, src_len, buffer, len, options);
 	if (ret < 0)
 		return ret;
@@ -229,22 +241,39 @@ int packet_read(int fd, char **src_buf, size_t *src_len,
 
 static char *packet_read_line_generic(int fd,
 				      char **src, size_t *src_len,
-				      int *dst_len)
+				      int *dst_len, int flags)
 {
 	int len = packet_read(fd, src, src_len,
 			      packet_buffer, sizeof(packet_buffer),
-			      PACKET_READ_CHOMP_NEWLINE);
+			      flags);
 	if (dst_len)
 		*dst_len = len;
-	return len ? packet_buffer : NULL;
+	return len > 0 ? packet_buffer : NULL;
 }
 
 char *packet_read_line(int fd, int *len_p)
 {
-	return packet_read_line_generic(fd, NULL, NULL, len_p);
+	return packet_read_line_generic(fd, NULL, NULL, len_p,
+			PACKET_READ_CHOMP_NEWLINE);
 }
 
 char *packet_read_line_buf(char **src, size_t *src_len, int *dst_len)
 {
-	return packet_read_line_generic(-1, src, src_len, dst_len);
+	return packet_read_line_generic(-1, src, src_len, dst_len,
+			PACKET_READ_CHOMP_NEWLINE);
+}
+
+char *packet_read_line_gentle(int fd, int *len_p)
+{
+	return packet_read_line_generic(fd, NULL, NULL, len_p,
+			PACKET_READ_CHOMP_NEWLINE |
+			PACKET_READ_GENTLE_ALL);
+}
+
+
+char *packet_read_line_buf_gentle(char **src, size_t *src_len, int *dst_len)
+{
+	return packet_read_line_generic(-1, src, src_len, dst_len,
+			PACKET_READ_CHOMP_NEWLINE |
+			PACKET_READ_GENTLE_ALL);
 }
diff --git a/pkt-line.h b/pkt-line.h
index 3cb9d91..553e42e 100644
--- a/pkt-line.h
+++ b/pkt-line.h
@@ -52,11 +52,15 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((f
  * condition 4 (truncated input), but instead return -1. However, we will still
  * die for the other 3 conditions.
  *
+ * If options contains PACKET_READ_GENTLE_ALL, we will not die on any of the
+ * conditions, but return -1 instead.
+ *
  * If options contains PACKET_READ_CHOMP_NEWLINE, a trailing newline (if
  * present) is removed from the buffer before returning.
  */
 #define PACKET_READ_GENTLE_ON_EOF (1u<<0)
 #define PACKET_READ_CHOMP_NEWLINE (1u<<1)
+#define PACKET_READ_GENTLE_ALL    (1u<<2)
 int packet_read(int fd, char **src_buffer, size_t *src_len, char
 		*buffer, unsigned size, int options);
 
@@ -75,6 +79,18 @@ char *packet_read_line(int fd, int *size);
  */
 char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
 
+/*
+ * Same as packet_read_line, but does not die on any errors (uses
+ * PACKET_READ_GENTLE_ALL).
+ */
+char *packet_read_line_gentle(int fd, int *len_p);
+
+/*
+ * Same as packet_read_line_buf, but does not die on any errors (uses
+ * PACKET_READ_GENTLE_ALL).
+ */
+char *packet_read_line_buf_gentle(char **src_buf, size_t *src_len, int *size);
+
 #define DEFAULT_PACKET_MAX 1000
 #define LARGE_PACKET_MAX 65520
 extern char packet_buffer[LARGE_PACKET_MAX];
-- 
2.7.4
Previous: Kevin WernNext: Junio C Hamano
Message 8 of 39 in “Resumable clone”
  1. 00/11 Resumable cloneKevin Wern, Sep 16, 2016
  2. 01/11 Resumable clone: create service git-prime-cloneKevin Wern, Sep 16, 2016
  3. Junio C HamanoSep 16, 2016
  4. Kevin WernSep 28, 2016
  5. 02/11 Resumable clone: add prime-clone endpointsKevin Wern, Sep 16, 2016
  6. Duy NguyenSep 19, 2016
  7. Kevin WernSep 28, 2016
  8. 03/11 pkt-line: create gentle packet_read_line functionsKevin Wern, Sep 16, 2016
  9. Junio C HamanoSep 16, 2016
  10. Kevin WernSep 28, 2016
  11. 04/11 Resumable clone: add prime-clone to remote-curlKevin Wern, Sep 16, 2016
  12. Duy NguyenSep 19, 2016
  13. Kevin WernSep 28, 2016
  14. 05/11 Resumable clone: add output parsing to connect.cKevin Wern, Sep 16, 2016
  15. 06/11 Resumable clone: implement transport_prime_cloneKevin Wern, Sep 16, 2016
  16. 07/11 Resumable clone: add resumable download to http/curlKevin Wern, Sep 16, 2016
  17. Junio C HamanoSep 16, 2016
  18. Kevin WernSep 28, 2016
  19. 08/11 Resumable clone: create transport_download_primerKevin Wern, Sep 16, 2016
  20. 10/11 run command: add RUN_COMMAND_NO_STDOUTKevin Wern, Sep 16, 2016
  21. Junio C HamanoSep 16, 2016
  22. Johannes SchindelinSep 18, 2016
  23. Kevin WernSep 28, 2016
  24. Junio C HamanoSep 28, 2016
  25. Kevin WernSep 28, 2016
  26. 09/11 path: add resumable markerKevin Wern, Sep 16, 2016
  27. Duy NguyenSep 19, 2016
  28. 11/11 Resumable clone: implement primer logic in git-cloneKevin Wern, Sep 16, 2016
  29. Junio C HamanoSep 16, 2016
  30. Kevin WernSep 28, 2016
  31. Duy NguyenSep 19, 2016
  32. Junio C HamanoSep 19, 2016
  33. Kevin WernSep 28, 2016
  34. Junio C HamanoSep 16, 2016
  35. Eric WongSep 27, 2016
  36. Junio C HamanoSep 27, 2016
  37. Junio C HamanoSep 28, 2016
  38. Junio C HamanoSep 28, 2016
  39. Eric WongSep 28, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.