Skip to content

Commit

Permalink
refs: explicitly propagate errno from refs_read_raw_ref
Browse files Browse the repository at this point in the history
The function refs_resolve_ref_unsafe_with_errno should produce an errno output.
Rather than taking the value from the errno (which might contain garbage
beforehand), explicitly propagate the failure_errno coming out of
refs_read_raw_ref().

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
  • Loading branch information
hanwen committed Jun 10, 2021
1 parent d865162 commit 2a9ebe4
Showing 1 changed file with 14 additions and 24 deletions.
38 changes: 14 additions & 24 deletions refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1686,11 +1686,11 @@ int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
type, failure_errno);
}

/* This function needs to return a meaningful errno on failure */
static const char *
refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
const char *refname, int resolve_flags,
struct object_id *oid, int *flags)
const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
const char *refname,
int resolve_flags,
struct object_id *oid,
int *flags, int *failure_errno)
{
static struct strbuf sb_refname = STRBUF_INIT;
struct object_id unused_oid;
Expand All @@ -1703,11 +1703,12 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
flags = &unused_flags;

*flags = 0;
*failure_errno = 0;

if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(refname)) {
errno = EINVAL;
*failure_errno = EINVAL;
return NULL;
}

Expand All @@ -1730,6 +1731,8 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
&read_flags, &read_failure)) {
*flags |= read_flags;

*failure_errno = read_failure;

/* In reading mode, refs must eventually resolve */
if (resolve_flags & RESOLVE_REF_READING)
return NULL;
Expand Down Expand Up @@ -1767,38 +1770,25 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(refname)) {
errno = EINVAL;
*failure_errno = EINVAL;
return NULL;
}

*flags |= REF_ISBROKEN | REF_BAD_NAME;
}
}

errno = ELOOP;
*failure_errno = ELOOP;
return NULL;
}

const char *refs_resolve_ref_unsafe(struct ref_store *refs, const char *refname,
int resolve_flags, struct object_id *oid,
int *flags)
{
const char *result = refs_resolve_ref_unsafe_implicit_errno(
refs, refname, resolve_flags, oid, flags);
errno = 0;
return result;
}

const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
const char *refname,
int resolve_flags,
struct object_id *oid,
int *flags, int *failure_errno)
{
const char *result = refs_resolve_ref_unsafe_implicit_errno(
refs, refname, resolve_flags, oid, flags);
*failure_errno = errno;
return result;
int ignore;
return refs_resolve_ref_unsafe_with_errno(refs, refname, resolve_flags,
oid, flags, &ignore);
}

/* backend functions */
Expand Down

0 comments on commit 2a9ebe4

Please sign in to comment.