@matheusbsbs / matheus-bagliano / commits / c9d1c8ba05
Fork 0

vcs-svn: improve reporting of input errors

Catch input errors and exit early enough to print a reasonable diagnosis based on errno. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: David Barr <david.barr@cordelta.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>

Jonathan Nieder committed Dec 28, 2010 at 04:30 UTC c9d1c8ba059577e64fb2213cb0c5f3c4619c7519
2 files changed +37 -5
vcs-svn/fast_export.c
+11 -2
@@ -63,14 +63,23 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
63 printf("progress Imported commit %"PRIu32".\n\n", revision);
64 }
65
66 +static void die_short_read(struct line_buffer *input)
67 +{
68 + if (buffer_ferror(input))
69 + die_errno("error reading dump file");
70 + die("invalid dump: unexpected end of file");
71 +}
72 +
73 void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input)
74 {
75 if (mode == REPO_MODE_LNK) {
76 /* svn symlink blobs start with "link " */
70 - buffer_skip_bytes(input, 5);
77 len -= 5;
78 + if (buffer_skip_bytes(input, 5) != 5)
79 + die_short_read(input);
80 }
81 printf("blob\nmark :%"PRIu32"\ndata %"PRIu32"\n", mark, len);
74 - buffer_copy_bytes(input, len);
82 + if (buffer_copy_bytes(input, len) != len)
83 + die_short_read(input);
84 fputc('\n', stdout);
85 }
vcs-svn/svndump.c
+26 -3
@@ -149,6 +149,13 @@ static void handle_property(uint32_t key, const char *val, uint32_t len,
149 }
150 }
151
152 +static void die_short_read(void)
153 +{
154 + if (buffer_ferror(&input))
155 + die_errno("error reading dump file");
156 + die("invalid dump: unexpected end of file");
157 +}
158 +
159 static void read_props(void)
160 {
161 uint32_t key = ~0;
@@ -170,12 +177,21 @@ static void read_props(void)
177 uint32_t len;
178 const char *val;
179 const char type = t[0];
180 + int ch;
181
182 if (!type || t[1] != ' ')
183 die("invalid property line: %s\n", t);
184 len = atoi(&t[2]);
185 val = buffer_read_string(&input, len);
178 - buffer_skip_bytes(&input, 1); /* Discard trailing newline. */
186 + if (!val || strlen(val) != len)
187 + die_short_read();
188 +
189 + /* Discard trailing newline. */
190 + ch = buffer_read_char(&input);
191 + if (ch == EOF)
192 + die_short_read();
193 + if (ch != '\n')
194 + die("invalid dump: expected newline after %s", val);
195
196 switch (type) {
197 case 'K':
@@ -344,7 +360,11 @@ void svndump_read(const char *url)
360 node_ctx.prop_delta = !strcmp(val, "true");
361 } else if (key == keys.content_length) {
362 len = atoi(val);
347 - buffer_read_line(&input);
363 + t = buffer_read_line(&input);
364 + if (!t)
365 + die_short_read();
366 + if (*t)
367 + die("invalid dump: expected blank line after content length header");
368 if (active_ctx == REV_CTX) {
369 read_props();
370 } else if (active_ctx == NODE_CTX) {
@@ -352,10 +372,13 @@ void svndump_read(const char *url)
372 active_ctx = REV_CTX;
373 } else {
374 fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len);
355 - buffer_skip_bytes(&input, len);
375 + if (buffer_skip_bytes(&input, len) != len)
376 + die_short_read();
377 }
378 }
379 }
380 + if (buffer_ferror(&input))
381 + die_short_read();
382 if (active_ctx == NODE_CTX)
383 handle_node();
384 if (active_ctx != DUMP_CTX)