From ce8ebcdaf31dd56955635808bba1a6df50601563 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Thu, 2 Feb 2012 03:57:23 -0600 Subject: vcs-svn: rename check_overflow and its arguments for clarity The canonical interpretation of a range a,b is as an interval [a,b), not [a,a+b), so this function taking argument names a and b feels unnatural. Use more explicit names "offset" and "len" to make the arguments' type and function clearer. While at it, rename the function to convey that we are making sure the sum of this offset and length do not overflow an off_t, not a size_t. [jn: split out from a patch from Ramsay Jones, then improved with advice from Thomas Rast, Dmitry Ivankov, and David Barr] Signed-off-by: Jonathan Nieder Improved-by: Dmitry Ivankov --- vcs-svn/sliding_window.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c index 1bac7a4c7f..c6c2effd30 100644 --- a/vcs-svn/sliding_window.c +++ b/vcs-svn/sliding_window.c @@ -31,15 +31,15 @@ static int read_to_fill_or_whine(struct line_buffer *file, return 0; } -static int check_overflow(off_t a, size_t b) +static int check_offset_overflow(off_t offset, size_t len) { - if (b > maximum_signed_value_of_type(off_t)) + if (len > maximum_signed_value_of_type(off_t)) return error("unrepresentable length in delta: " - "%"PRIuMAX" > OFF_MAX", (uintmax_t) b); - if (signed_add_overflows(a, (off_t) b)) + "%"PRIuMAX" > OFF_MAX", (uintmax_t) len); + if (signed_add_overflows(offset, (off_t) len)) return error("unrepresentable offset in delta: " "%"PRIuMAX" + %"PRIuMAX" > OFF_MAX", - (uintmax_t) a, (uintmax_t) b); + (uintmax_t) offset, (uintmax_t) len); return 0; } @@ -48,9 +48,9 @@ int move_window(struct sliding_view *view, off_t off, size_t width) off_t file_offset; assert(view); assert(view->width <= view->buf.len); - assert(!check_overflow(view->off, view->buf.len)); + assert(!check_offset_overflow(view->off, view->buf.len)); - if (check_overflow(off, width)) + if (check_offset_overflow(off, width)) return -1; if (off < view->off || off + width < view->off + view->width) return error("invalid delta: window slides left"); -- cgit v1.2.3 From 2d54b9ea8b99df7b448f64a7847f7f3879964e12 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 2 Feb 2012 04:19:35 -0600 Subject: vcs-svn: allow import of > 4GiB files There is no reason in principle that an svn-format dump would not be able to represent a file whose length does not fit in a 32-bit integer. Use off_t consistently (instead of uint32_t) to represent file lengths so we can handle that. Most of our code is already ready to do that without this patch and already passes values of type off_t around. The type mismatch due to stragglers was noticed with gcc -Wtype-limits. Inspired-by: Ramsay Jones Signed-off-by: Jonathan Nieder --- vcs-svn/fast_export.c | 15 +++++++++------ vcs-svn/fast_export.h | 4 ++-- vcs-svn/svndump.c | 21 +++++++++++++++------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 19d7c34c25..b823b8519c 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -227,15 +227,18 @@ static long apply_delta(off_t len, struct line_buffer *input, return ret; } -void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input) +void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input) { + assert(len >= 0); if (mode == REPO_MODE_LNK) { /* svn symlink blobs start with "link " */ + if (len < 5) + die("invalid dump: symlink too short for \"link\" prefix"); len -= 5; if (buffer_skip_bytes(input, 5) != 5) die_short_read(input); } - printf("data %"PRIu32"\n", len); + printf("data %"PRIuMAX"\n", (uintmax_t) len); if (buffer_copy_bytes(input, len) != len) die_short_read(input); fputc('\n', stdout); @@ -297,12 +300,12 @@ int fast_export_ls(const char *path, uint32_t *mode, struct strbuf *dataref) void fast_export_blob_delta(uint32_t mode, uint32_t old_mode, const char *old_data, - uint32_t len, struct line_buffer *input) + off_t len, struct line_buffer *input) { long postimage_len; - if (len > maximum_signed_value_of_type(off_t)) - die("enormous delta"); - postimage_len = apply_delta((off_t) len, input, old_data, old_mode); + + assert(len >= 0); + postimage_len = apply_delta(len, input, old_data, old_mode); if (mode == REPO_MODE_LNK) { buffer_skip_bytes(&postimage, strlen("link ")); postimage_len -= strlen("link "); diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index 43d05b65ef..aa629f54ff 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -14,10 +14,10 @@ void fast_export_begin_commit(uint32_t revision, const char *author, const struct strbuf *log, const char *uuid, const char *url, unsigned long timestamp); void fast_export_end_commit(uint32_t revision); -void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input); +void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input); void fast_export_blob_delta(uint32_t mode, uint32_t old_mode, const char *old_data, - uint32_t len, struct line_buffer *input); + off_t len, struct line_buffer *input); /* If there is no such file at that rev, returns -1, errno == ENOENT. */ int fast_export_ls_rev(uint32_t rev, const char *path, diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index ca63760fe2..644fdc71ba 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -40,7 +40,8 @@ static struct line_buffer input = LINE_BUFFER_INIT; static struct { - uint32_t action, propLength, textLength, srcRev, type; + uint32_t action, propLength, srcRev, type; + off_t text_length; struct strbuf src, dst; uint32_t text_delta, prop_delta; } node_ctx; @@ -61,7 +62,7 @@ static void reset_node_ctx(char *fname) node_ctx.type = 0; node_ctx.action = NODEACT_UNKNOWN; node_ctx.propLength = LENGTH_UNKNOWN; - node_ctx.textLength = LENGTH_UNKNOWN; + node_ctx.text_length = -1; strbuf_reset(&node_ctx.src); node_ctx.srcRev = 0; strbuf_reset(&node_ctx.dst); @@ -209,7 +210,7 @@ static void handle_node(void) { const uint32_t type = node_ctx.type; const int have_props = node_ctx.propLength != LENGTH_UNKNOWN; - const int have_text = node_ctx.textLength != LENGTH_UNKNOWN; + const int have_text = node_ctx.text_length != -1; /* * Old text for this node: * NULL - directory or bug @@ -291,12 +292,12 @@ static void handle_node(void) } if (!node_ctx.text_delta) { fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline"); - fast_export_data(node_ctx.type, node_ctx.textLength, &input); + fast_export_data(node_ctx.type, node_ctx.text_length, &input); return; } fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline"); fast_export_blob_delta(node_ctx.type, old_mode, old_data, - node_ctx.textLength, &input); + node_ctx.text_length, &input); } static void begin_revision(void) @@ -409,7 +410,15 @@ void svndump_read(const char *url) break; case sizeof("Text-content-length"): if (!constcmp(t, "Text-content-length")) { - node_ctx.textLength = atoi(val); + char *end; + uintmax_t textlen; + + textlen = strtoumax(val, &end, 10); + if (!isdigit(*val) || *end) + die("invalid dump: non-numeric length %s", val); + if (textlen > maximum_signed_value_of_type(off_t)) + die("unrepresentable length in dump: %s", val); + node_ctx.text_length = (off_t) textlen; break; } if (constcmp(t, "Prop-content-length")) -- cgit v1.2.3 From 5b8bf02930674a5c2cba42d919ba3c0c96bf58e4 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 2 Feb 2012 04:28:02 -0600 Subject: vcs-svn: suppress -Wtype-limits warning On 32-bit architectures with 64-bit file offsets, gcc 4.3 and earlier produce the following warning: CC vcs-svn/sliding_window.o vcs-svn/sliding_window.c: In function `check_overflow': vcs-svn/sliding_window.c:36: warning: comparison is always false \ due to limited range of data type The warning appears even when gcc is run without any warning flags (PR12963). In later versions it can be reproduced with -Wtype-limits, which is implied by -Wextra. On 64-bit architectures it really is possible for a size_t not to be representable as an off_t so the check being warned about is not actually redundant. But even false positives are distracting. Avoid the warning by making the "len" argument to check_overflow a uintmax_t; no functional change intended. Reported-by: Ramsay Jones Signed-off-by: Jonathan Nieder --- vcs-svn/sliding_window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c index c6c2effd30..ec2707c9c4 100644 --- a/vcs-svn/sliding_window.c +++ b/vcs-svn/sliding_window.c @@ -31,15 +31,15 @@ static int read_to_fill_or_whine(struct line_buffer *file, return 0; } -static int check_offset_overflow(off_t offset, size_t len) +static int check_offset_overflow(off_t offset, uintmax_t len) { if (len > maximum_signed_value_of_type(off_t)) return error("unrepresentable length in delta: " - "%"PRIuMAX" > OFF_MAX", (uintmax_t) len); + "%"PRIuMAX" > OFF_MAX", len); if (signed_add_overflows(offset, (off_t) len)) return error("unrepresentable offset in delta: " "%"PRIuMAX" + %"PRIuMAX" > OFF_MAX", - (uintmax_t) offset, (uintmax_t) len); + (uintmax_t) offset, len); return 0; } -- cgit v1.2.3 From 3b8a3051733e754dad587e5a73fba7f367c7e0db Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:30 +1000 Subject: vcs-svn: drop no-op reset methods Since v1.7.5~42^2~6 (vcs-svn: remove buffer_read_string) buffer_reset() does nothing thus fast_export_reset() also. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- test-line-buffer.c | 1 - test-svn-fe.c | 2 -- vcs-svn/fast_export.c | 5 ----- vcs-svn/fast_export.h | 1 - vcs-svn/line_buffer.c | 4 ---- vcs-svn/line_buffer.h | 1 - vcs-svn/svndump.c | 2 -- 7 files changed, 16 deletions(-) diff --git a/test-line-buffer.c b/test-line-buffer.c index 7ec9b13c9b..ef1d7bae14 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -87,6 +87,5 @@ int main(int argc, char *argv[]) die("input error"); if (ferror(stdout)) die("output error"); - buffer_reset(&stdin_buf); return 0; } diff --git a/test-svn-fe.c b/test-svn-fe.c index 332a5f711d..83633a21e5 100644 --- a/test-svn-fe.c +++ b/test-svn-fe.c @@ -31,9 +31,7 @@ static int apply_delta(int argc, char *argv[]) die_errno("cannot close preimage"); if (buffer_deinit(&delta)) die_errno("cannot close delta"); - buffer_reset(&preimage); strbuf_release(&preimage_view.buf); - buffer_reset(&delta); return 0; } diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index b823b8519c..b4be91cc76 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -42,11 +42,6 @@ void fast_export_deinit(void) die_errno("error closing fast-import feedback stream"); } -void fast_export_reset(void) -{ - buffer_reset(&report_buffer); -} - void fast_export_delete(const char *path) { putchar('D'); diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index aa629f54ff..8823aca15c 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -6,7 +6,6 @@ struct line_buffer; void fast_export_init(int fd); void fast_export_deinit(void); -void fast_export_reset(void); void fast_export_delete(const char *path); void fast_export_modify(const char *path, uint32_t mode, const char *dataref); diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 01fcb842f1..57cc1cec03 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -124,7 +124,3 @@ off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes) } return done; } - -void buffer_reset(struct line_buffer *buf) -{ -} diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h index 8901f214ba..ee23b4f490 100644 --- a/vcs-svn/line_buffer.h +++ b/vcs-svn/line_buffer.h @@ -14,7 +14,6 @@ struct line_buffer { int buffer_init(struct line_buffer *buf, const char *filename); int buffer_fdinit(struct line_buffer *buf, int fd); int buffer_deinit(struct line_buffer *buf); -void buffer_reset(struct line_buffer *buf); int buffer_tmpfile_init(struct line_buffer *buf); FILE *buffer_tmpfile_rewind(struct line_buffer *buf); /* prepare to write. */ diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 644fdc71ba..f6c0d4c8a0 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -499,8 +499,6 @@ void svndump_deinit(void) void svndump_reset(void) { - fast_export_reset(); - buffer_reset(&input); strbuf_release(&dump_ctx.uuid); strbuf_release(&dump_ctx.url); strbuf_release(&rev_ctx.log); -- cgit v1.2.3 From 4a5de8dd79879d737e172a5d7e4196c6bf99e57d Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:25 +1000 Subject: vcs-svn: avoid self-assignment in dummy initialization of pre_off Without this change, clang complains: vcs-svn/svndiff.c:298:3: warning: Assigned value is garbage or undefined off_t pre_off = pre_off; /* stupid GCC... */ ^ ~~~~~~~ This code uses an old and common idiom for suppressing an "uninitialized variable" warning, and clang is wrong to warn about it. The idiom tells the compiler to leave the variable uninitialized, which saves a few bytes of code size, and, more importantly, allows valgrind to check at runtime that the variable is properly initialized by the time it is used. But MSVC and clang do not know that idiom, so let's avoid it in vcs-svn/ code. Initialize pre_off to -1, a recognizably meaningless value, to allow future code changes that cause pre_off to be used before it is initialized to be caught early. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/svndiff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index 1647c1a780..c89d9623f4 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -295,7 +295,7 @@ int svndiff0_apply(struct line_buffer *delta, off_t delta_len, if (read_magic(delta, &delta_len)) return -1; while (delta_len) { /* For each window: */ - off_t pre_off = pre_off; /* stupid GCC... */ + off_t pre_off = -1; size_t pre_len; if (read_offset(delta, &pre_off, &delta_len) || -- cgit v1.2.3 From 4a1613194af218afb99be0e14af449e86852d06e Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:26 +1000 Subject: vcs-svn: simplify cleanup in apply_one_window Currently the cleanup code looks like this: free resources return 0; error_out: free resources return -1; Avoid duplicating the "free resources" part by keeping the return value in a variable and sharing code between the success and exceptional case: ret = 0; out: free resources return ret; Noticed in the svn-dump-fast-export project, where using the error() macro in void context produces a warning. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/svndiff.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index c89d9623f4..e810d0c3ff 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -258,6 +258,7 @@ static int apply_window_in_core(struct window *ctx) static int apply_one_window(struct line_buffer *delta, off_t *delta_len, struct sliding_view *preimage, FILE *out) { + int rv = -1; struct window ctx = WINDOW_INIT(preimage); size_t out_len; size_t instructions_len; @@ -275,16 +276,15 @@ static int apply_one_window(struct line_buffer *delta, off_t *delta_len, if (apply_window_in_core(&ctx)) goto error_out; if (ctx.out.len != out_len) { - error("invalid delta: incorrect postimage length"); + rv = error("invalid delta: incorrect postimage length"); goto error_out; } if (write_strbuf(&ctx.out, out)) goto error_out; - window_release(&ctx); - return 0; + rv = 0; error_out: window_release(&ctx); - return -1; + return rv; } int svndiff0_apply(struct line_buffer *delta, off_t delta_len, -- cgit v1.2.3 From d8d8708bd6a56818ee3a85007e36a8ff201f9512 Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:27 +1000 Subject: vcs-svn: use constcmp instead of prefixcmp Since the length of t is already known, we can simplify a little by using memcmp() instead of strncmp() to carry out a prefix comparison. All nearby code already does this. Noticed in the standalone svn-dump-fast-export project which has not needed to implement prefixcmp() yet. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/svndump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index f6c0d4c8a0..c5d07a6687 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -361,7 +361,7 @@ void svndump_read(const char *url) reset_rev_ctx(atoi(val)); break; case sizeof("Node-path"): - if (prefixcmp(t, "Node-")) + if (constcmp(t, "Node-")) continue; if (!constcmp(t + strlen("Node-"), "path")) { if (active_ctx == NODE_CTX) -- cgit v1.2.3 From 53153e8382966e35362d072ba17ba5887e3c0851 Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:28 +1000 Subject: vcs-svn: use strstr instead of memmem memmem is a GNU extension. Avoiding it makes the code clearer and makes it easier for projects that don't share git's compat/ code, such as the standalone svn-dump-fast-export project, to reuse the vcs-svn/ library. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/fast_export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index b4be91cc76..854b328d43 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -158,7 +158,7 @@ static int parse_cat_response_line(const char *header, off_t *len) if (ends_with(header, headerlen, " missing")) return error("cat-blob reports missing blob: %s", header); - type = memmem(header, headerlen, " blob ", strlen(" blob ")); + type = strstr(header, " blob "); if (!type) return error("cat-blob header has wrong object type: %s", header); n = strtoumax(type + strlen(" blob "), (char **) &end, 10); -- cgit v1.2.3 From 6a0b4438afc22551533dccc221bdf802ee4ed5ee Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:29 +1000 Subject: vcs-svn: suppress signed/unsigned comparison warnings These are already safe because both sides of the comparison are nonnegative. This would normally not be important because Git is not -Wsign-compare clean anyway, but we like to keep the vcs-svn/ lib to a higher standard for convenience using it in other projects. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/fast_export.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 854b328d43..1f04697866 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -254,7 +254,7 @@ static int parse_ls_response(const char *response, uint32_t *mode, } /* Mode. */ - if (response_end - response < strlen("100644") || + if (response_end - response < (signed) strlen("100644") || response[strlen("100644")] != ' ') die("invalid ls response: missing mode: %s", response); *mode = 0; @@ -267,7 +267,7 @@ static int parse_ls_response(const char *response, uint32_t *mode, } /* ' blob ' or ' tree ' */ - if (response_end - response < strlen(" blob ") || + if (response_end - response < (signed) strlen(" blob ") || (response[1] != 'b' && response[1] != 't')) die("unexpected ls response: not a tree or blob: %s", response); response += strlen(" blob "); -- cgit v1.2.3 From c68038effed2f1031848330cca46e85fc79e3ab2 Mon Sep 17 00:00:00 2001 From: David Barr Date: Fri, 1 Jun 2012 00:41:29 +1000 Subject: vcs-svn: suppress a signed/unsigned comparison warning The preceding code checks that view->max_off is nonnegative and (off + width) fits in an off_t, so this code is already safe. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/sliding_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c index ec2707c9c4..f11d490995 100644 --- a/vcs-svn/sliding_window.c +++ b/vcs-svn/sliding_window.c @@ -54,7 +54,7 @@ int move_window(struct sliding_view *view, off_t off, size_t width) return -1; if (off < view->off || off + width < view->off + view->width) return error("invalid delta: window slides left"); - if (view->max_off >= 0 && view->max_off < off + width) + if (view->max_off >= 0 && view->max_off < off + (off_t) width) return error("delta preimage ends early"); file_offset = view->off + view->buf.len; -- cgit v1.2.3 From 96a60a87098534b74e3b98e636ec65daea9823a7 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 5 Jul 2012 22:21:09 -0500 Subject: vcs-svn: suppress a signed/unsigned comparison warning All callers pass a nonnegative delta_len, so the code is already safe. Add an assertion to ensure that remains so and add a cast to keep clang and gcc -Wsign-compare from worrying. Reported-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/svndiff.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index e810d0c3ff..74c97c4543 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -77,8 +77,9 @@ static int error_short_read(struct line_buffer *input) static int read_chunk(struct line_buffer *delta, off_t *delta_len, struct strbuf *buf, size_t len) { + assert(*delta_len >= 0); strbuf_reset(buf); - if (len > *delta_len || + if (len > (uintmax_t) *delta_len || buffer_read_binary(delta, buf, len) != len) return error_short_read(delta); *delta_len -= buf->len; @@ -290,7 +291,7 @@ error_out: int svndiff0_apply(struct line_buffer *delta, off_t delta_len, struct sliding_view *preimage, FILE *postimage) { - assert(delta && preimage && postimage); + assert(delta && preimage && postimage && delta_len >= 0); if (read_magic(delta, &delta_len)) return -1; -- cgit v1.2.3 From e32b79cb3211992505d68c421a3f66b29590d72c Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 5 Jul 2012 22:47:47 -0500 Subject: vcs-svn: allow 64-bit Prop-Content-Length Currently the vcs-svn/ library only pays attention to the presence of the Prop-Content-Length field and doesn't care about its value, but some day we might care about the value. Parse it as an off_t instead of arbitrarily limiting to 32 bits for intuitiveness. So now you can import from a dump with more than 2 GiB of properties for a node. In practice that isn't likely to happen often, and this is mostly meant as a cleanup. Based-on-patch-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/svndump.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index c5d07a6687..a7f3ea64a5 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -34,14 +34,13 @@ #define NODE_CTX 2 /* node metadata */ #define INTERNODE_CTX 3 /* between nodes */ -#define LENGTH_UNKNOWN (~0) #define DATE_RFC2822_LEN 31 static struct line_buffer input = LINE_BUFFER_INIT; static struct { - uint32_t action, propLength, srcRev, type; - off_t text_length; + uint32_t action, srcRev, type; + off_t prop_length, text_length; struct strbuf src, dst; uint32_t text_delta, prop_delta; } node_ctx; @@ -61,7 +60,7 @@ static void reset_node_ctx(char *fname) { node_ctx.type = 0; node_ctx.action = NODEACT_UNKNOWN; - node_ctx.propLength = LENGTH_UNKNOWN; + node_ctx.prop_length = -1; node_ctx.text_length = -1; strbuf_reset(&node_ctx.src); node_ctx.srcRev = 0; @@ -209,7 +208,7 @@ static void read_props(void) static void handle_node(void) { const uint32_t type = node_ctx.type; - const int have_props = node_ctx.propLength != LENGTH_UNKNOWN; + const int have_props = node_ctx.prop_length != -1; const int have_text = node_ctx.text_length != -1; /* * Old text for this node: @@ -273,7 +272,7 @@ static void handle_node(void) if (have_props) { if (!node_ctx.prop_delta) node_ctx.type = type; - if (node_ctx.propLength) + if (node_ctx.prop_length) read_props(); } @@ -409,22 +408,26 @@ void svndump_read(const char *url) node_ctx.srcRev = atoi(val); break; case sizeof("Text-content-length"): - if (!constcmp(t, "Text-content-length")) { + if (constcmp(t, "Text") && constcmp(t, "Prop")) + continue; + if (constcmp(t + 4, "-content-length")) + continue; + { char *end; - uintmax_t textlen; + uintmax_t len; - textlen = strtoumax(val, &end, 10); + len = strtoumax(val, &end, 10); if (!isdigit(*val) || *end) die("invalid dump: non-numeric length %s", val); - if (textlen > maximum_signed_value_of_type(off_t)) + if (len > maximum_signed_value_of_type(off_t)) die("unrepresentable length in dump: %s", val); - node_ctx.text_length = (off_t) textlen; + + if (*t == 'T') + node_ctx.text_length = (off_t) len; + else + node_ctx.prop_length = (off_t) len; break; } - if (constcmp(t, "Prop-content-length")) - continue; - node_ctx.propLength = atoi(val); - break; case sizeof("Text-delta"): if (!constcmp(t, "Text-delta")) { node_ctx.text_delta = !strcmp(val, "true"); -- cgit v1.2.3