diff options
author | Vicent Marti <vicent@github.com> | 2014-08-25 18:18:06 +0200 |
---|---|---|
committer | Vicent Marti <vicent@github.com> | 2014-08-25 18:18:06 +0200 |
commit | 2c1de697e04bf19e55efef415fcf0ec3e592511a (patch) | |
tree | 1fd5fcb4ab3b4f71e0d6716617d1b198c2a7c438 | |
parent | d28b2b7a5ff608ce8f3da0e0b6a4c75afcf1e82c (diff) | |
parent | 8f6073f63e42c2a3ff3b6fbb20729c7a911be30f (diff) | |
download | libgit2-2c1de697e04bf19e55efef415fcf0ec3e592511a.tar.gz |
Merge pull request #2527 from jacquesg/refspec-crash
Check if the refspec matches before transforming
-rw-r--r-- | src/refspec.c | 16 | ||||
-rw-r--r-- | tests/network/refspecs.c | 48 |
2 files changed, 57 insertions, 7 deletions
diff --git a/src/refspec.c b/src/refspec.c index 77c58c84e..9f0df35a7 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -223,7 +223,13 @@ static int refspec_transform( int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) { - git_buf_sanitize(out); + assert(out && spec && name); + git_buf_sanitize(out); + + if (!git_refspec_src_matches(spec, name)) { + giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name); + return -1; + } if (!spec->pattern) return git_buf_puts(out, spec->dst); @@ -233,7 +239,13 @@ int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *nam int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) { - git_buf_sanitize(out); + assert(out && spec && name); + git_buf_sanitize(out); + + if (!git_refspec_dst_matches(spec, name)) { + giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name); + return -1; + } if (!spec->pattern) return git_buf_puts(out, spec->src); diff --git a/tests/network/refspecs.c b/tests/network/refspecs.c index aa9b36e58..c6bcb10e8 100644 --- a/tests/network/refspecs.c +++ b/tests/network/refspecs.c @@ -88,7 +88,7 @@ void test_network_refspecs__parsing(void) assert_refspec(GIT_DIRECTION_FETCH, "refs/pull/*/head:refs/remotes/origin/pr/*", true); } -void assert_transform(const char *refspec, const char *name, const char *result) +static void assert_valid_transform(const char *refspec, const char *name, const char *result) { git_refspec spec; git_buf buf = GIT_BUF_INIT; @@ -103,8 +103,46 @@ void assert_transform(const char *refspec, const char *name, const char *result) void test_network_refspecs__transform_mid_star(void) { - assert_transform("refs/pull/*/head:refs/remotes/origin/pr/*", "refs/pull/23/head", "refs/remotes/origin/pr/23"); - assert_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/master", "refs/remotes/origin/master"); - assert_transform("refs/heads/*:refs/heads/*", "refs/heads/master", "refs/heads/master"); - assert_transform("refs/*:refs/*", "refs/heads/master", "refs/heads/master"); + assert_valid_transform("refs/pull/*/head:refs/remotes/origin/pr/*", "refs/pull/23/head", "refs/remotes/origin/pr/23"); + assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/master", "refs/remotes/origin/master"); + assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/user/feature", "refs/remotes/origin/user/feature"); + assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/master", "refs/heads/master"); + assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/user/feature", "refs/heads/user/feature"); + assert_valid_transform("refs/*:refs/*", "refs/heads/master", "refs/heads/master"); +} + +static void assert_invalid_transform(const char *refspec, const char *name) +{ + git_refspec spec; + git_buf buf = GIT_BUF_INIT; + + git_refspec__parse(&spec, refspec, true); + cl_git_fail(git_refspec_transform(&buf, &spec, name)); + + git_buf_free(&buf); + git_refspec__free(&spec); +} + +void test_network_refspecs__invalid(void) +{ + assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "master"); + assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "refs/headz/master"); +} + +static void assert_invalid_rtransform(const char *refspec, const char *name) +{ + git_refspec spec; + git_buf buf = GIT_BUF_INIT; + + git_refspec__parse(&spec, refspec, true); + cl_git_fail(git_refspec_rtransform(&buf, &spec, name)); + + git_buf_free(&buf); + git_refspec__free(&spec); +} + +void test_network_refspecs__invalid_reverse(void) +{ + assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "master"); + assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "refs/remotes/o/master"); } |