Skip to content

Commit dce4bab

Browse files
mhaggergitster
authored andcommitted
add_ref(): verify that the refname is formatted correctly
In add_ref(), verify that the refname is formatted correctly before adding it to the ref_list. Here we have to allow refname components that start with ".", since (for example) the remote protocol uses synthetic reference name ".have". So add a new REFNAME_DOT_COMPONENT flag that can be passed to check_refname_format() to allow leading dots. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7cb3684 commit dce4bab

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

refs.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static struct ref_list *add_ref(const char *name, const unsigned char *sha1,
5656
entry = xmalloc(sizeof(struct ref_list) + len);
5757
hashcpy(entry->sha1, sha1);
5858
hashclr(entry->peeled);
59+
if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
60+
die("Reference has invalid format: '%s'", name);
5961
memcpy(entry->name, name, len);
6062
entry->flag = flag;
6163
entry->next = list;
@@ -900,7 +902,7 @@ static inline int bad_ref_char(int ch)
900902
* the length of the component found, or -1 if the component is not
901903
* legal.
902904
*/
903-
static int check_refname_component(const char *ref)
905+
static int check_refname_component(const char *ref, int flags)
904906
{
905907
const char *cp;
906908
char last = '\0';
@@ -919,8 +921,16 @@ static int check_refname_component(const char *ref)
919921
}
920922
if (cp == ref)
921923
return -1; /* Component has zero length. */
922-
if (ref[0] == '.')
923-
return -1; /* Component starts with '.'. */
924+
if (ref[0] == '.') {
925+
if (!(flags & REFNAME_DOT_COMPONENT))
926+
return -1; /* Component starts with '.'. */
927+
/*
928+
* Even if leading dots are allowed, don't allow "."
929+
* as a component (".." is prevented by a rule above).
930+
*/
931+
if (ref[1] == '\0')
932+
return -1; /* Component equals ".". */
933+
}
924934
if (cp - ref >= 5 && !memcmp(cp - 5, ".lock", 5))
925935
return -1; /* Refname ends with ".lock". */
926936
return cp - ref;
@@ -932,7 +942,7 @@ int check_refname_format(const char *ref, int flags)
932942

933943
while (1) {
934944
/* We are at the start of a path component. */
935-
component_len = check_refname_component(ref);
945+
component_len = check_refname_component(ref, flags);
936946
if (component_len < 0) {
937947
if ((flags & REFNAME_REFSPEC_PATTERN) &&
938948
ref[0] == '*' &&

refs.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,18 @@ extern int for_each_reflog(each_ref_fn, void *);
9999

100100
#define REFNAME_ALLOW_ONELEVEL 1
101101
#define REFNAME_REFSPEC_PATTERN 2
102+
#define REFNAME_DOT_COMPONENT 4
102103

103104
/*
104105
* Return 0 iff ref has the correct format for a refname according to
105106
* the rules described in Documentation/git-check-ref-format.txt. If
106107
* REFNAME_ALLOW_ONELEVEL is set in flags, then accept one-level
107108
* reference names. If REFNAME_REFSPEC_PATTERN is set in flags, then
108109
* allow a "*" wildcard character in place of one of the name
109-
* components. No leading or repeated slashes are accepted.
110+
* components. No leading or repeated slashes are accepted. If
111+
* REFNAME_DOT_COMPONENT is set in flags, then allow refname
112+
* components to start with "." (but not a whole component equal to
113+
* "." or "..").
110114
*/
111115
extern int check_refname_format(const char *ref, int flags);
112116

0 commit comments

Comments
 (0)