[PATCH 04/16] vcs-svn: improve reporting of input errors
From: David Barr <hidden>
Date: 2016-06-15 22:50:48
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Jonathan Nieder <redacted> Catch input errors and exit early enough to print a reasonable diagnosis based on errno. Signed-off-by: Jonathan Nieder <redacted> Signed-off-by: David Barr <redacted> --- vcs-svn/fast_export.c | 13 +++++++++++-- vcs-svn/svndump.c | 22 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 1d50512..4748253 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c@@ -120,15 +120,24 @@ static const char *get_response_line(void) die("unexpected end of fast-import feedback"); } +static void die_short_read(struct line_buffer *input) +{ + if (buffer_ferror(input)) + die_errno("error reading dump file"); + die("invalid dump: unexpected end of file"); +} + void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input) { if (mode == REPO_MODE_LNK) { /* svn symlink blobs start with "link " */ - buffer_skip_bytes(input, 5); len -= 5; + if (buffer_skip_bytes(input, 5) != 5) + die_short_read(input); } printf("data %"PRIu32"\n", len); - buffer_copy_bytes(input, len); + if (buffer_copy_bytes(input, len) != len) + die_short_read(input); fputc('\n', stdout); }
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 7bc2d3d..dbb9c16 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c@@ -133,6 +133,13 @@ static void handle_property(const char *key, const char *val, uint32_t len, } } +static void die_short_read(void) +{ + if (buffer_ferror(&input)) + die_errno("error reading dump file"); + die("invalid dump: unexpected end of file"); +} + static void read_props(void) { char key[16] = {0};
@@ -159,7 +166,9 @@ static void read_props(void) die("invalid property line: %s\n", t); len = atoi(&t[2]); val = buffer_read_string(&input, len); - buffer_skip_bytes(&input, 1); /* Discard trailing newline. */ + /* Discard trailing newline. */ + if (buffer_skip_bytes(&input, 1) != 1) + die_short_read(); switch (type) { case 'K':
@@ -402,7 +411,11 @@ void svndump_read(const char *url) if (memcmp(t, "Content-length", 14)) continue; len = atoi(val); - buffer_read_line(&input); + t = buffer_read_line(&input); + if (!t) + die_short_read(); + if (*t) + die("invalid dump: expected blank line after content length header"); if (active_ctx == REV_CTX) { read_props(); } else if (active_ctx == NODE_CTX) {
@@ -410,10 +423,13 @@ void svndump_read(const char *url) active_ctx = INTERNODE_CTX; } else { fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len); - buffer_skip_bytes(&input, len); + if (buffer_skip_bytes(&input, len) != len) + die_short_read(); } } } + if (buffer_ferror(&input)) + die_short_read(); if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX)
--
1.7.3.2.846.gf4b062