Commit 2c1de697 by Vicent Marti

Merge pull request #2527 from jacquesg/refspec-crash

Check if the refspec matches before transforming
parents d28b2b7a 8f6073f6
......@@ -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);
......
......@@ -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");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment