branch_get() can return NULL (so far on detached HEAD only) but some
code paths in builtin/branch.c cannot deal with that and cause
segfaults. Fix it.

While at there, make sure to bail out when the user gives 2 or more
arguments, but only the first one is processed.

Reported-by: Per Cederqvist <ced...@opera.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 builtin/branch.c  | 20 ++++++++++++++++++++
 t/t3200-branch.sh | 21 +++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/builtin/branch.c b/builtin/branch.c
index 6371bf9..c1d688e 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -889,6 +889,13 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
        } else if (new_upstream) {
                struct branch *branch = branch_get(argv[0]);
 
+               if (argc > 1)
+                       die(_("too many branches to set new upstream"));
+
+               if (!branch)
+                       die(_("could not figure out the branch name from '%s'"),
+                           argc == 1 ? argv[0] : "HEAD");
+
                if (!ref_exists(branch->refname))
                        die(_("branch '%s' does not exist"), branch->name);
 
@@ -901,6 +908,13 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
                struct branch *branch = branch_get(argv[0]);
                struct strbuf buf = STRBUF_INIT;
 
+               if (argc > 1)
+                       die(_("too many branches to unset upstream"));
+
+               if (!branch)
+                       die(_("could not figure out the branch name from '%s'"),
+                           argc == 1 ? argv[0] : "HEAD");
+
                if (!branch_has_merge_config(branch)) {
                        die(_("Branch '%s' has no upstream information"), 
branch->name);
                }
@@ -916,6 +930,12 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
                int branch_existed = 0, remote_tracking = 0;
                struct strbuf buf = STRBUF_INIT;
 
+               if (!strcmp(argv[0], "HEAD"))
+                       die(_("it does not make sense to create 'HEAD' 
manually"));
+
+               if (!branch)
+                       die(_("could not figure out the branch name from 
'%s'"), argv[0]);
+
                if (kinds != REF_LOCAL_BRANCH)
                        die(_("-a and -r options to 'git branch' do not make 
sense with a branch name"));
 
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index f3e0e4a..12f1e4a 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -42,6 +42,10 @@ test_expect_success \
     'git branch a/b/c should create a branch' \
     'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c'
 
+test_expect_success \
+    'git branch HEAD should fail' \
+    'test_must_fail git branch HEAD'
+
 cat >expect <<EOF
 $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000        
branch: Created from master
 EOF
@@ -388,6 +392,14 @@ test_expect_success \
     'git tag foobar &&
      test_must_fail git branch --track my11 foobar'
 
+test_expect_success '--set-upstream-to fails on multiple branches' \
+    'test_must_fail git branch --set-upstream-to master a b c'
+
+test_expect_success '--set-upstream-to fails on detached HEAD' \
+    'git checkout HEAD^{} &&
+     test_must_fail git branch --set-upstream-to master &&
+     git checkout -'
+
 test_expect_success 'use --set-upstream-to modify HEAD' \
     'test_config branch.master.remote foo &&
      test_config branch.master.merge foo &&
@@ -417,6 +429,15 @@ test_expect_success 'test --unset-upstream on HEAD' \
      test_must_fail git branch --unset-upstream
 '
 
+test_expect_success '--unset-upstream should fail on multiple branches' \
+    'test_must_fail git branch --unset-upstream a b c'
+
+test_expect_success '--unset-upstream should fail on detached HEAD' \
+    'git checkout HEAD^{} &&
+     test_must_fail git branch --unset-upstream &&
+     git checkout -
+'
+
 test_expect_success 'test --unset-upstream on a particular branch' \
     'git branch my15
      git branch --set-upstream-to master my14 &&
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to