Skip to content

Commit 5ec4c22

Browse files
peffgitster
authored andcommitted
ref-filter: factor out refname component counting
The "lstrip" and "rstrip" options to the %(refname) placeholder both accept a negative length, which asks us to keep that many path components (rather than stripping that many). The code to count components and convert the negative value to a positive was copied from lstrip to rstrip in 1a34728 (ref-filter: add an 'rstrip=<N>' option to atoms which deal with refnames, 2017-01-10). Let's factor it out into a separate function. This reduces duplication and also makes the lstrip/rstrip functions much easier to follow, since the bulk of their code is now the actual stripping. Note that the computed "remaining" value is currently stored as a "long", so in theory that's what our function should return. But this is purely historical. When the variable was added in 0571979 (tag: do not show ambiguous tag names as "tags/foo", 2016-01-25), we parsed the value from strtol(), and thus used a long. But these days we take "len" as an int, and also use an int to count up components. So let's just consistently use int here. This value could only overflow in a pathological case (e.g., 4GB worth of "a/a/...") and even then will not result in out-of-bounds memory access (we keep stripping until we run out of string to parse). The minimal Myers diff here is a little hard to read; with --patience the code movement is shown much more clearly. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 67ad421 commit 5ec4c22

1 file changed

Lines changed: 11 additions & 23 deletions

File tree

ref-filter.c

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,12 +2173,8 @@ static inline char *copy_advance(char *dst, const char *src)
21732173
return dst;
21742174
}
21752175

2176-
static const char *lstrip_ref_components(const char *refname, int len)
2176+
static int normalize_component_count(const char *refname, int len)
21772177
{
2178-
long remaining = len;
2179-
const char *start = xstrdup(refname);
2180-
const char *to_free = start;
2181-
21822178
if (len < 0) {
21832179
int i;
21842180
const char *p = refname;
@@ -2192,8 +2188,16 @@ static const char *lstrip_ref_components(const char *refname, int len)
21922188
* because we count the number of '/', but the number
21932189
* of components is one more than the no of '/').
21942190
*/
2195-
remaining = i + len + 1;
2191+
len = i + len + 1;
21962192
}
2193+
return len;
2194+
}
2195+
2196+
static const char *lstrip_ref_components(const char *refname, int len)
2197+
{
2198+
int remaining = normalize_component_count(refname, len);
2199+
const char *start = xstrdup(refname);
2200+
const char *to_free = start;
21972201

21982202
while (remaining > 0) {
21992203
switch (*start++) {
@@ -2213,26 +2217,10 @@ static const char *lstrip_ref_components(const char *refname, int len)
22132217

22142218
static const char *rstrip_ref_components(const char *refname, int len)
22152219
{
2216-
long remaining = len;
2220+
int remaining = normalize_component_count(refname, len);
22172221
const char *start = xstrdup(refname);
22182222
const char *to_free = start;
22192223

2220-
if (len < 0) {
2221-
int i;
2222-
const char *p = refname;
2223-
2224-
/* Find total no of '/' separated path-components */
2225-
for (i = 0; p[i]; p[i] == '/' ? i++ : *p++)
2226-
;
2227-
/*
2228-
* The number of components we need to strip is now
2229-
* the total minus the components to be left (Plus one
2230-
* because we count the number of '/', but the number
2231-
* of components is one more than the no of '/').
2232-
*/
2233-
remaining = i + len + 1;
2234-
}
2235-
22362224
while (remaining-- > 0) {
22372225
char *p = strrchr(start, '/');
22382226
if (!p) {

0 commit comments

Comments
 (0)