René Scharfe <[email protected]> writes:
> lookup_blob() etc. can return NULL if the referenced object isn't of the
> expected type. In theory it's wrong to reference the object member in
> that case. In practice it's OK because it's located at offset 0 for all
> types, so the pointer arithmetic (NULL + 0) is optimized out by the
> compiler. The issue is reported by Clang's AddressSanitizer, though.
>
> Avoid the ASan error by casting the results of the lookup functions to
> struct object pointers. That works fine with NULL pointers as well. We
> already rely on the object member being first in all object types in
> other places in the code.
>
> Signed-off-by: Rene Scharfe <[email protected]>
> ---
Yikes, that is tricky.
Taking the address of .object field appears to be a lot cleaner and
more kosher than casting, but from the compiler's point of view it's
quite the opposite. Sigh.
Thanks. The patch itself looks like the right solution to me.
> tag.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/tag.c b/tag.c
> index 7e10acfb6e..fcbe012f7a 100644
> --- a/tag.c
> +++ b/tag.c
> @@ -142,13 +142,13 @@ int parse_tag_buffer(struct tag *item, const void
> *data, unsigned long size)
> bufptr = nl + 1;
>
> if (!strcmp(type, blob_type)) {
> - item->tagged = &lookup_blob(&oid)->object;
> + item->tagged = (struct object *)lookup_blob(&oid);
> } else if (!strcmp(type, tree_type)) {
> - item->tagged = &lookup_tree(&oid)->object;
> + item->tagged = (struct object *)lookup_tree(&oid);
> } else if (!strcmp(type, commit_type)) {
> - item->tagged = &lookup_commit(&oid)->object;
> + item->tagged = (struct object *)lookup_commit(&oid);
> } else if (!strcmp(type, tag_type)) {
> - item->tagged = &lookup_tag(&oid)->object;
> + item->tagged = (struct object *)lookup_tag(&oid);
> } else {
> error("Unknown type %s", type);
> item->tagged = NULL;