From 9308b7f3ca9bbe7e76b16c832617a8c6aea5ade3 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sat, 1 Jul 2017 20:31:08 +0200 Subject: [PATCH] read_packed_refs(): die if `packed-refs` contains bogus data The old code ignored any lines that it didn't understand, including unterminated lines. This is dangerous. Instead, `die()` if the `packed-refs` file contains any unterminated lines or lines that we don't know how to handle. This fixes the tests added in the last commit. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/packed-backend.c | 10 +++++++--- t/t3210-pack-refs.sh | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 377c775adb..a28befbfa3 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -229,6 +229,9 @@ static struct packed_ref_cache *read_packed_refs(const char *packed_refs_file) const char *refname; const char *traits; + if (!line.len || line.buf[line.len - 1] != '\n') + die("unterminated line in %s: %s", packed_refs_file, line.buf); + if (skip_prefix(line.buf, "# pack-refs with:", &traits)) { if (strstr(traits, " fully-peeled ")) peeled = PEELED_FULLY; @@ -253,9 +256,7 @@ static struct packed_ref_cache *read_packed_refs(const char *packed_refs_file) (peeled == PEELED_TAGS && starts_with(refname, "refs/tags/"))) last->flag |= REF_KNOWS_PEELED; add_ref_entry(dir, last); - continue; - } - if (last && + } else if (last && line.buf[0] == '^' && line.len == PEELED_LINE_LENGTH && line.buf[PEELED_LINE_LENGTH - 1] == '\n' && @@ -267,6 +268,9 @@ static struct packed_ref_cache *read_packed_refs(const char *packed_refs_file) * reference: */ last->flag |= REF_KNOWS_PEELED; + } else { + strbuf_setlen(&line, line.len - 1); + die("unexpected line in %s: %s", packed_refs_file, line.buf); } } diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 4b65836283..2bb4b25ed9 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -194,7 +194,7 @@ test_expect_success 'notice d/f conflict with existing ref' ' test_must_fail git branch foo/bar/baz/lots/of/extra/components ' -test_expect_failure 'reject packed-refs with unterminated line' ' +test_expect_success 'reject packed-refs with unterminated line' ' cp .git/packed-refs .git/packed-refs.bak && test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && printf "%s" "$HEAD refs/zzzzz" >>.git/packed-refs && @@ -203,7 +203,7 @@ test_expect_failure 'reject packed-refs with unterminated line' ' test_cmp expected_err err ' -test_expect_failure 'reject packed-refs containing junk' ' +test_expect_success 'reject packed-refs containing junk' ' cp .git/packed-refs .git/packed-refs.bak && test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && printf "%s\n" "bogus content" >>.git/packed-refs && @@ -212,7 +212,7 @@ test_expect_failure 'reject packed-refs containing junk' ' test_cmp expected_err err ' -test_expect_failure 'reject packed-refs with a short SHA-1' ' +test_expect_success 'reject packed-refs with a short SHA-1' ' cp .git/packed-refs .git/packed-refs.bak && test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && printf "%.7s %s\n" $HEAD refs/zzzzz >>.git/packed-refs &&