avoid using mksnpath for refs
Like the previous commit, we'd like to avoid the assumption that refs fit into PATH_MAX-sized buffers. These callsites have an extra twist, though: they write the refnames using mksnpath. This does two things beyond a regular snprintf: 1. It quietly writes "/bad-path/" when truncation occurs. This saves the caller having to check the error code, but if you aren't actually feeding the result to a system call (and we aren't here), it's questionable. 2. It calls cleanup_path(), which removes leading instances of "./". That's questionable when dealing with refnames, as we could silently canonicalize a syntactically bogus refname into a valid one. Let's convert each case to use a strbuf. This is preferable to xstrfmt() because we can reuse the same buffer as we loop. Signed-off-by: Jeff King <peff@peff.net>
This commit is contained in:

committed by
Junio C Hamano

parent
7f897b6f17
commit
6cd4a8982d
44
refs.c
44
refs.c
@ -429,29 +429,31 @@ int expand_ref(const char *str, int len, unsigned char *sha1, char **ref)
|
|||||||
{
|
{
|
||||||
const char **p, *r;
|
const char **p, *r;
|
||||||
int refs_found = 0;
|
int refs_found = 0;
|
||||||
|
struct strbuf fullref = STRBUF_INIT;
|
||||||
|
|
||||||
*ref = NULL;
|
*ref = NULL;
|
||||||
for (p = ref_rev_parse_rules; *p; p++) {
|
for (p = ref_rev_parse_rules; *p; p++) {
|
||||||
char fullref[PATH_MAX];
|
|
||||||
unsigned char sha1_from_ref[20];
|
unsigned char sha1_from_ref[20];
|
||||||
unsigned char *this_result;
|
unsigned char *this_result;
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
this_result = refs_found ? sha1_from_ref : sha1;
|
this_result = refs_found ? sha1_from_ref : sha1;
|
||||||
mksnpath(fullref, sizeof(fullref), *p, len, str);
|
strbuf_reset(&fullref);
|
||||||
r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING,
|
strbuf_addf(&fullref, *p, len, str);
|
||||||
|
r = resolve_ref_unsafe(fullref.buf, RESOLVE_REF_READING,
|
||||||
this_result, &flag);
|
this_result, &flag);
|
||||||
if (r) {
|
if (r) {
|
||||||
if (!refs_found++)
|
if (!refs_found++)
|
||||||
*ref = xstrdup(r);
|
*ref = xstrdup(r);
|
||||||
if (!warn_ambiguous_refs)
|
if (!warn_ambiguous_refs)
|
||||||
break;
|
break;
|
||||||
} else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) {
|
} else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
|
||||||
warning("ignoring dangling symref %s.", fullref);
|
warning("ignoring dangling symref %s.", fullref.buf);
|
||||||
} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {
|
} else if ((flag & REF_ISBROKEN) && strchr(fullref.buf, '/')) {
|
||||||
warning("ignoring broken ref %s.", fullref);
|
warning("ignoring broken ref %s.", fullref.buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
strbuf_release(&fullref);
|
||||||
return refs_found;
|
return refs_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,21 +462,22 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
|
|||||||
char *last_branch = substitute_branch_name(&str, &len);
|
char *last_branch = substitute_branch_name(&str, &len);
|
||||||
const char **p;
|
const char **p;
|
||||||
int logs_found = 0;
|
int logs_found = 0;
|
||||||
|
struct strbuf path = STRBUF_INIT;
|
||||||
|
|
||||||
*log = NULL;
|
*log = NULL;
|
||||||
for (p = ref_rev_parse_rules; *p; p++) {
|
for (p = ref_rev_parse_rules; *p; p++) {
|
||||||
unsigned char hash[20];
|
unsigned char hash[20];
|
||||||
char path[PATH_MAX];
|
|
||||||
const char *ref, *it;
|
const char *ref, *it;
|
||||||
|
|
||||||
mksnpath(path, sizeof(path), *p, len, str);
|
strbuf_reset(&path);
|
||||||
ref = resolve_ref_unsafe(path, RESOLVE_REF_READING,
|
strbuf_addf(&path, *p, len, str);
|
||||||
|
ref = resolve_ref_unsafe(path.buf, RESOLVE_REF_READING,
|
||||||
hash, NULL);
|
hash, NULL);
|
||||||
if (!ref)
|
if (!ref)
|
||||||
continue;
|
continue;
|
||||||
if (reflog_exists(path))
|
if (reflog_exists(path.buf))
|
||||||
it = path;
|
it = path.buf;
|
||||||
else if (strcmp(ref, path) && reflog_exists(ref))
|
else if (strcmp(ref, path.buf) && reflog_exists(ref))
|
||||||
it = ref;
|
it = ref;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
@ -485,6 +488,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
|
|||||||
if (!warn_ambiguous_refs)
|
if (!warn_ambiguous_refs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
strbuf_release(&path);
|
||||||
free(last_branch);
|
free(last_branch);
|
||||||
return logs_found;
|
return logs_found;
|
||||||
}
|
}
|
||||||
@ -944,6 +948,7 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
|
|||||||
static char **scanf_fmts;
|
static char **scanf_fmts;
|
||||||
static int nr_rules;
|
static int nr_rules;
|
||||||
char *short_name;
|
char *short_name;
|
||||||
|
struct strbuf resolved_buf = STRBUF_INIT;
|
||||||
|
|
||||||
if (!nr_rules) {
|
if (!nr_rules) {
|
||||||
/*
|
/*
|
||||||
@ -1002,7 +1007,6 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
|
|||||||
*/
|
*/
|
||||||
for (j = 0; j < rules_to_fail; j++) {
|
for (j = 0; j < rules_to_fail; j++) {
|
||||||
const char *rule = ref_rev_parse_rules[j];
|
const char *rule = ref_rev_parse_rules[j];
|
||||||
char refname[PATH_MAX];
|
|
||||||
|
|
||||||
/* skip matched rule */
|
/* skip matched rule */
|
||||||
if (i == j)
|
if (i == j)
|
||||||
@ -1013,9 +1017,10 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
|
|||||||
* (with this previous rule) to a valid ref
|
* (with this previous rule) to a valid ref
|
||||||
* read_ref() returns 0 on success
|
* read_ref() returns 0 on success
|
||||||
*/
|
*/
|
||||||
mksnpath(refname, sizeof(refname),
|
strbuf_reset(&resolved_buf);
|
||||||
rule, short_name_len, short_name);
|
strbuf_addf(&resolved_buf, rule,
|
||||||
if (ref_exists(refname))
|
short_name_len, short_name);
|
||||||
|
if (ref_exists(resolved_buf.buf))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,10 +1028,13 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
|
|||||||
* short name is non-ambiguous if all previous rules
|
* short name is non-ambiguous if all previous rules
|
||||||
* haven't resolved to a valid ref
|
* haven't resolved to a valid ref
|
||||||
*/
|
*/
|
||||||
if (j == rules_to_fail)
|
if (j == rules_to_fail) {
|
||||||
|
strbuf_release(&resolved_buf);
|
||||||
return short_name;
|
return short_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strbuf_release(&resolved_buf);
|
||||||
free(short_name);
|
free(short_name);
|
||||||
return xstrdup(refname);
|
return xstrdup(refname);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user