From bdc8d8b4b4504cdc432dd384a212443e2514d1fe Mon Sep 17 00:00:00 2001 From: David Barr Date: Thu, 9 Sep 2010 18:54:23 +1000 Subject: [PATCH] vcs-svn: Limit bytes read and written strictly limit bytes output by svn-da update svn-da tests to inclue output limit limit bytes of source image read by svn-da limit bytes of delta read by svn-da fix parse error by removing read-ahead Signed-off-by: David Barr --- contrib/svn-fe/svn-da.c | 18 +++++++++++--- contrib/svn-fe/svn-da.txt | 4 +--- t/t9010-svn-fe.sh | 60 +++++++++++++++++++++++++++++++++-------------- vcs-svn/svndiff.c | 22 +++++++++-------- vcs-svn/svndiff.h | 2 +- 5 files changed, 71 insertions(+), 35 deletions(-) diff --git a/contrib/svn-fe/svn-da.c b/contrib/svn-fe/svn-da.c index 2b7b0a17c0..3b83f00980 100644 --- a/contrib/svn-fe/svn-da.c +++ b/contrib/svn-fe/svn-da.c @@ -3,17 +3,29 @@ * You may freely use, modify, distribute, and relicense it. */ +#include #include #include #include "svndiff.h" int main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: svn-da delta postimage"); + size_t out = SIZE_MAX; + size_t in = SIZE_MAX; + size_t len = SIZE_MAX; + if (argc < 2 || argc > 5) { + fprintf(stderr, "usage: svn-da delta " + "[[[postimage_length] preimage_length] delta_length] " + "postimage"); return 1; } - if (svndiff0_apply(argv[1], SIZE_MAX, stdin, stdout)) + if (argc >= 3) + out = strtoull(argv[2], NULL, 10); + if (argc >= 4) + in = strtoull(argv[3], NULL, 10); + if (argc >= 5) + len = strtoull(argv[4], NULL, 10); + if (svndiff0_apply(argv[1], len, out, in, stdin, stdout)) return 1; return 0; } diff --git a/contrib/svn-fe/svn-da.txt b/contrib/svn-fe/svn-da.txt index e739ab3b37..437d1dfb53 100644 --- a/contrib/svn-fe/svn-da.txt +++ b/contrib/svn-fe/svn-da.txt @@ -7,7 +7,7 @@ svn-da - Apply a given diff0 to a given source and produce fulltext SYNOPSIS -------- -svn-da DIFF actual && - test_cmp "$expected" actual +. ./test-lib.sh + +svnfe_bin=$GIT_EXEC_PATH/contrib/svn-fe/svn-fe +svnda_bin=$GIT_EXEC_PATH/contrib/svn-fe/svn-da +svnconf=$PWD/svnconf +export svnconf + +svn_cmd () { + [ -d "$svnconf" ] || mkdir "$svnconf" + orig_svncmd="$1"; shift + if [ -z "$orig_svncmd" ]; then + svn + return + fi + svn "$orig_svncmd" --config-dir "$svnconf" "$@" +} + +test_parse() { + diff0=$1 + source=$2 + expected=$3 + postsize=`wc -c < "$TEST_DIRECTORY/$expected"` + presize=`wc -c < "$TEST_DIRECTORY/$source"` + diffsize=`wc -c < "$TEST_DIRECTORY/$diff0"` + test_expect_success SVNDA "$diff0" ' + $svnda_bin "$TEST_DIRECTORY/$diff0" "$postsize" "$presize" "$diffsize" <"$TEST_DIRECTORY/$source" >actual && + test_cmp "$TEST_DIRECTORY/$expected" actual ' } test_dump() { label=$1 - dump="$TEST_DIRECTORY/$2" - expectation=${3:-success} - test_expect_$expectation "$dump" ' + dump=$2 + test_expect_success SVNFE "$dump" ' svnadmin create "$label-svn" && - svnadmin load "$label-svn" <"$dump" && + svnadmin load "$label-svn" < "$TEST_DIRECTORY/$dump" && svn_cmd export "file://$PWD/$label-svn" "$label-svnco" && git init "$label-git" && - test-svn-fe "$dump" >"$label.fe" && + $svnfe_bin <"$TEST_DIRECTORY/$dump" >"$label.fe" && ( cd "$label-git" && - git fast-import <../"$label.fe" + git fast-import < ../"$label.fe" ) && ( cd "$label-svnco" && @@ -39,8 +55,16 @@ test_dump() { ' } +if [ -x $svnfe_bin ]; then + test_set_prereq SVNFE +fi + +if [ -x $svnda_bin ]; then + test_set_prereq SVNDA +fi + test_dump simple t9135/svn.dump -test_svndiff t9135/newdata.diff0 t9135/blank.done t9135/newdata.done failure -test_svndiff t9135/src.diff0 t9135/newdata.done t9135/src.done failure +test_parse t9135/newdata.diff0 t9135/blank.done t9135/newdata.done +test_parse t9135/src.diff0 t9135/newdata.done t9135/src.done test_done diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index aa01ac10c6..9eca93cef5 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -302,7 +302,8 @@ static int do_instructions(struct window *ctx) } static int apply_within(const struct view *preimage, size_t *out_offset, - FILE *outf, size_t *len_remaining) + FILE *outf, size_t *len_remaining, + size_t *out_remaining) { struct window ctx; @@ -357,10 +358,13 @@ static int apply_within(const struct view *preimage, size_t *out_offset, free(ctx.out); return -1; } + if (ctx.out_len > *out_remaining) + ctx.out_len = *out_remaining; if (fwrite(ctx.out, 1, ctx.out_len, outf) == ctx.out_len) { /* Success. */ free(ctx.out); *out_offset = ctx.out_off; + *out_remaining -= ctx.out_len; return 0; } error("Error writing patched file: %s", strerror(errno)); @@ -389,7 +393,7 @@ static int parse_magic(size_t *len) /* * Apply a delta from the file named by delta, truncated to len bytes. */ -int svndiff0_apply(const char *delta, size_t len, +int svndiff0_apply(const char *delta, size_t len, size_t out, size_t in, FILE *preimage, FILE *postimage) { struct view preimage_view = {preimage, NULL, 0, 0}; @@ -400,7 +404,7 @@ int svndiff0_apply(const char *delta, size_t len, return error("cannot open %s: %s\n", delta, strerror(errno)); if (parse_magic(&len)) return -1; - while (len > 0) { + while (len > 0 && out > 0) { /* New window. */ size_t pre_off, pre_len; int ch; @@ -408,17 +412,15 @@ int svndiff0_apply(const char *delta, size_t len, return -1; if (parse_int(&pre_len, &len)) return -1; + if (pre_len > in) + pre_len = in; if (move_window(&preimage_view, pre_off, pre_len)) return -1; - if (apply_within(&preimage_view, &out_offset, postimage, &len)) + in -= pre_len; + if (apply_within(&preimage_view, &out_offset, postimage, &len, &out)) return -1; - - /* Check for EOF (or error) */ - if ((ch = buffer_read_char()) == EOF) + if (ferror(stdin) || feof(stdin)) break; - if (buffer_unread_char(ch)) - return error("cannot unget %c: %s\n", - ch, strerror(errno)); } return buffer_deinit(); } diff --git a/vcs-svn/svndiff.h b/vcs-svn/svndiff.h index 54b57b17c5..a1778304b1 100644 --- a/vcs-svn/svndiff.h +++ b/vcs-svn/svndiff.h @@ -5,7 +5,7 @@ * Read in a delta using the line_buffer library and use it to * patch preimage, writing the result to postimage. */ -extern int svndiff0_apply(const char *delta, size_t len, +extern int svndiff0_apply(const char *delta, size_t len, size_t out, size_t in, FILE *preimage, FILE *postimage); #endif -- 2.11.4.GIT