From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: David Barr <david.barr@cordelta.com>,
Ramkumar Ramachandra <artagnon@gmail.com>,
Sverre Rabbelier <srabbelier@gmail.com>
Subject: [PATCH 4/4] vcs-svn: improve reporting of input errors
Date: Tue, 28 Dec 2010 04:54:10 -0600 [thread overview]
Message-ID: <20101228105410.GD13360@burratino> (raw)
In-Reply-To: <20101228104503.GA5422@burratino>
Catch input errors and exit early enough to print a reasonable
diagnosis based on errno.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Patches 1 and 2 first appeared in the svndiff0 series[1] (and that
is the application I have in mind in sending them now).
This patch #4 is just a demo. Untested, I'm afraid. I would be
very interested in ideas for automatically testing it --- how to
easily stimulate error paths?
Good night,
Jonathan
[1] http://thread.gmane.org/gmane.comp.version-control.git/158731
vcs-svn/fast_export.c | 13 ++++++++++-
vcs-svn/svndump.c | 53 ++++++++++++++++++++++++++++++++++++++----------
2 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 256a052..dc0ae4e 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -62,14 +62,23 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
printf("progress Imported commit %d.\n\n", revision);
}
+static void die_short_read(void)
+{
+ if (buffer_ferror())
+ die_errno("error reading dump file");
+ die("invalid dump: unexpected end of file");
+}
+
void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len)
{
if (mode == REPO_MODE_LNK) {
/* svn symlink blobs start with "link " */
- buffer_skip_bytes(5);
len -= 5;
+ if (buffer_skip_bytes(5) != 5)
+ die_short_read();
}
printf("blob\nmark :%d\ndata %d\n", mark, len);
- buffer_copy_bytes(len);
+ if (buffer_copy_bytes(len) != len)
+ die_short_read();
fputc('\n', stdout);
}
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 630eeb5..09bcebd 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -107,20 +107,37 @@ static void init_keys(void)
keys.content_length = pool_intern("Content-length");
}
+static void die_short_read(void)
+{
+ if (buffer_ferror())
+ die_errno("error reading dump file");
+ die("invalid dump: unexpected end of file");
+}
+
static void read_props(void)
{
uint32_t len;
uint32_t key = ~0;
char *val = NULL;
- char *t;
- while ((t = buffer_read_line()) && strcmp(t, "PROPS-END")) {
+ for (;;) {
+ char *t = buffer_read_line();
+ if (!t)
+ die_short_read();
+ if (!strcmp(t, "PROPS-END"))
+ return;
if (!strncmp(t, "K ", 2)) {
len = atoi(&t[2]);
- key = pool_intern(buffer_read_string(len));
- buffer_read_line();
+ t = buffer_read_line();
+ if (!t)
+ die_short_read();
+ if (strlen(t) != len)
+ die("invalid dump: incorrect key length");
+ key = pool_intern(t);
} else if (!strncmp(t, "V ", 2)) {
len = atoi(&t[2]);
val = buffer_read_string(len);
+ if (!t)
+ die_short_read();
if (key == keys.svn_log) {
/* Value length excludes terminating nul. */
rev_ctx.log = log_copy(len + 1, val);
@@ -135,7 +152,11 @@ static void read_props(void)
node_ctx.type = REPO_MODE_LNK;
}
key = ~0;
- buffer_read_line();
+ t = buffer_read_line();
+ if (!t)
+ die_short_read();
+ if (*t)
+ die("invalid dump: incorrect value length");
}
}
}
@@ -176,10 +197,12 @@ static void handle_node(void)
if (node_ctx.propLength == LENGTH_UNKNOWN && node_ctx.srcMode)
node_ctx.type = node_ctx.srcMode;
- if (node_ctx.mark)
+ if (node_ctx.mark) {
fast_export_blob(node_ctx.type, node_ctx.mark, node_ctx.textLength);
- else if (node_ctx.textLength != LENGTH_UNKNOWN)
- buffer_skip_bytes(node_ctx.textLength);
+ } else if (node_ctx.textLength != LENGTH_UNKNOWN) {
+ if (buffer_skip_bytes(node_ctx.textLength) != node_ctx.textLength)
+ die_short_read();
+ }
}
static void handle_revision(void)
@@ -250,7 +273,11 @@ void svndump_read(const char *url)
node_ctx.propLength = atoi(val);
} else if (key == keys.content_length) {
len = atoi(val);
- buffer_read_line();
+ t = buffer_read_line();
+ 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) {
@@ -258,10 +285,13 @@ void svndump_read(const char *url)
active_ctx = REV_CTX;
} else {
fprintf(stderr, "Unexpected content length header: %d\n", len);
- buffer_skip_bytes(len);
+ if (buffer_skip_bytes(len) != len)
+ die_short_read();
}
}
}
+ if (buffer_ferror())
+ die_short_read();
if (active_ctx == NODE_CTX)
handle_node();
if (active_ctx != DUMP_CTX)
@@ -270,7 +300,8 @@ void svndump_read(const char *url)
void svndump_init(const char *filename)
{
- buffer_init(filename);
+ if (buffer_init(filename))
+ die_errno("cannot open dump file: %s", filename);
repo_init();
reset_dump_ctx(~0);
reset_rev_ctx(0);
--
1.7.2.3.554.gc9b5c.dirty
next prev parent reply other threads:[~2010-12-28 10:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-28 10:45 [RFC/PATCH 0/4] improving svn-fe error handling Jonathan Nieder
2010-12-28 10:47 ` [PATCH 1/4] vcs-svn: allow input errors to be detected promptly Jonathan Nieder
2010-12-28 10:48 ` [PATCH 2/4] vcs-svn: make buffer_skip_bytes return length read Jonathan Nieder
2010-12-28 10:49 ` [PATCH 3/4] vcs-svn: make buffer_copy_bytes " Jonathan Nieder
2010-12-28 10:54 ` Jonathan Nieder [this message]
2011-01-04 10:16 ` [PATCH 4/4] vcs-svn: improve reporting of input errors Jonathan Nieder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101228105410.GD13360@burratino \
--to=jrnieder@gmail.com \
--cc=artagnon@gmail.com \
--cc=david.barr@cordelta.com \
--cc=git@vger.kernel.org \
--cc=srabbelier@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).