summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/refs.c b/refs.c
index 26b001453b..9ccaf40172 100644
--- a/refs.c
+++ b/refs.c
@@ -647,19 +647,24 @@ int for_each_ref(each_ref_fn fn, void *cb_data)
return do_for_each_ref("refs/", fn, 0, 0, cb_data);
}
+int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
+{
+ return do_for_each_ref(prefix, fn, strlen(prefix), 0, cb_data);
+}
+
int for_each_tag_ref(each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref("refs/tags/", fn, 10, 0, cb_data);
+ return for_each_ref_in("refs/tags/", fn, cb_data);
}
int for_each_branch_ref(each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref("refs/heads/", fn, 11, 0, cb_data);
+ return for_each_ref_in("refs/heads/", fn, cb_data);
}
int for_each_remote_ref(each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref("refs/remotes/", fn, 13, 0, cb_data);
+ return for_each_ref_in("refs/remotes/", fn, cb_data);
}
int for_each_rawref(each_ref_fn fn, void *cb_data)
@@ -676,6 +681,7 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)
* - it has double dots "..", or
* - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
* - it ends with a "/".
+ * - it ends with ".lock"
*/
static inline int bad_ref_char(int ch)
@@ -693,7 +699,7 @@ static inline int bad_ref_char(int ch)
int check_ref_format(const char *ref)
{
- int ch, level, bad_type;
+ int ch, level, bad_type, last;
int ret = CHECK_REF_FORMAT_OK;
const char *cp = ref;
@@ -717,21 +723,28 @@ int check_ref_format(const char *ref)
return CHECK_REF_FORMAT_ERROR;
}
+ last = ch;
/* scan the rest of the path component */
while ((ch = *cp++) != 0) {
bad_type = bad_ref_char(ch);
- if (bad_type) {
+ if (bad_type)
return CHECK_REF_FORMAT_ERROR;
- }
if (ch == '/')
break;
- if (ch == '.' && *cp == '.')
+ if (last == '.' && ch == '.')
return CHECK_REF_FORMAT_ERROR;
+ if (last == '@' && ch == '{')
+ return CHECK_REF_FORMAT_ERROR;
+ last = ch;
}
level++;
if (!ch) {
+ if (ref <= cp - 2 && cp[-2] == '.')
+ return CHECK_REF_FORMAT_ERROR;
if (level < 2)
return CHECK_REF_FORMAT_ONELEVEL;
+ if (has_extension(ref, ".lock"))
+ return CHECK_REF_FORMAT_ERROR;
return ret;
}
}