send-pack: tighten checks for remote names
authorJunio C Hamano <junkio@cox.net>
Wed, 13 Dec 2006 18:30:11 +0000 (10:30 -0800)
committerJunio C Hamano <junkio@cox.net>
Wed, 13 Dec 2006 18:30:11 +0000 (10:30 -0800)
"git push $URL HEAD~6" created a bogus ref HEAD~6 immediately
under $GIT_DIR of the remote repository.  While we should keep
refspecs that have arbitrary extended SHA-1 expression on the
source side working (e.g. "HEAD~6:refs/tags/yesterday"), we
should not create bogus ref on the other end.

Signed-off-by: Junio C Hamano <junkio@cox.net>
refs.c
send-pack.c

diff --git a/refs.c b/refs.c
index 96ea8b6907b1e4be9c7b8575ff7e4a36f5a7a5f8..e56abb8585130a284b5f597cc8388c015b8e66d5 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -534,7 +534,7 @@ int check_ref_format(const char *ref)
                level++;
                if (!ch) {
                        if (level < 2)
-                               return -1; /* at least of form "heads/blah" */
+                               return -2; /* at least of form "heads/blah" */
                        return 0;
                }
        }
index 328dbbc16a7c529659fabd2704a2a6b1cc625210..cc884f3b2debbaadfc3c42cda20074257fa48a65 100644 (file)
@@ -406,6 +406,25 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
        return ret;
 }
 
+static void verify_remote_names(int nr_heads, char **heads)
+{
+       int i;
+
+       for (i = 0; i < nr_heads; i++) {
+               const char *remote = strchr(heads[i], ':');
+
+               remote = remote ? (remote + 1) : heads[i];
+               switch (check_ref_format(remote)) {
+               case 0: /* ok */
+               case -2: /* ok but a single level -- that is fine for
+                         * a match pattern.
+                         */
+                       continue;
+               }
+               die("remote part of refspec is not a valid name in %s",
+                   heads[i]);
+       }
+}
 
 int main(int argc, char **argv)
 {
@@ -457,6 +476,8 @@ int main(int argc, char **argv)
                usage(send_pack_usage);
        if (heads && send_all)
                usage(send_pack_usage);
+       verify_remote_names(nr_heads, heads);
+
        pid = git_connect(fd, dest, exec);
        if (pid < 0)
                return 1;