Merge branch 'rr/forbid-bs-in-ref'
authorJunio C Hamano <gitster@pobox.com>
Sat, 23 May 2009 08:39:45 +0000 (01:39 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 23 May 2009 08:39:45 +0000 (01:39 -0700)
* rr/forbid-bs-in-ref:
Disallow '\' in ref names

1  2 
Documentation/git-check-ref-format.txt
refs.c
index 0873e60f7f61f51143e88fd8637b34627620a7dd,bf434544158fee814a9647a11102b7e1b1165720..0b7982ea76633e45b8d3073cd275ea74a757c0eb
@@@ -25,10 -25,6 +25,10 @@@ imposes the following rules on how refe
    grouping, but no slash-separated component can begin with a
    dot `.`.
  
 +. They must contain at least one `/`. This enforces the presence of a
 +  category like `heads/`, `tags/` etc. but the actual names are not
 +  restricted.
 +
  . They cannot have two consecutive dots `..` anywhere.
  
  . They cannot have ASCII control characters (i.e. bytes whose
@@@ -42,6 -38,8 +42,8 @@@
  
  . They cannot contain a sequence `@{`.
  
+ - They cannot contain a `\\`.
  These rules make it easy for shell script based tools to parse
  reference names, pathname expansion by the shell when a reference name is used
  unquoted (by mistake), and also avoids ambiguities in certain
diff --combined refs.c
index 2b1f0f0e6ed7978107e5b488f8d12f6276e482a4,fc33bc6ac4b4abcffd814afcd6ee76d4cc73c28c..bb4bdc9eac9a3cb5a122437f14a0f175511b1493
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -682,12 -682,13 +682,13 @@@ int for_each_rawref(each_ref_fn fn, voi
   * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
   * - it ends with a "/".
   * - it ends with ".lock"
+  * - it contains a "\" (backslash)
   */
  
  static inline int bad_ref_char(int ch)
  {
        if (((unsigned) ch) <= ' ' ||
-           ch == '~' || ch == '^' || ch == ':')
+           ch == '~' || ch == '^' || ch == ':' || ch == '\\')
                return 1;
        /* 2.13 Pattern Matching Notation */
        if (ch == '?' || ch == '[') /* Unsupported */
@@@ -1002,10 -1003,12 +1003,10 @@@ int delete_ref(const char *refname, con
                } else {
                        path = git_path("%s", refname);
                }
 -              err = unlink(path);
 -              if (err && errno != ENOENT) {
 +              err = unlink_or_warn(path);
 +              if (err && errno != ENOENT)
                        ret = 1;
 -                      error("unlink(%s) failed: %s",
 -                            path, strerror(errno));
 -              }
 +
                if (!(delopt & REF_NODEREF))
                        lock->lk->filename[i] = '.';
        }
         */
        ret |= repack_without_ref(refname);
  
 -      err = unlink(git_path("logs/%s", lock->ref_name));
 -      if (err && errno != ENOENT)
 -              warning("unlink(%s) failed: %s",
 -                      git_path("logs/%s", lock->ref_name), strerror(errno));
 +      unlink_or_warn(git_path("logs/%s", lock->ref_name));
        invalidate_cached_refs();
        unlock_ref(lock);
        return ret;
@@@ -1376,7 -1382,7 +1377,7 @@@ int create_symref(const char *ref_targe
        if (adjust_shared_perm(git_HEAD)) {
                error("Unable to fix permissions on %s", lockpath);
        error_unlink_return:
 -              unlink(lockpath);
 +              unlink_or_warn(lockpath);
        error_free_return:
                free(git_HEAD);
                return -1;