From a650ad996db85b64643970dd7dc5920f989260a0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 18 Dec 2025 12:35:40 +0900 Subject: odb: do not use "blank" substitute for NULL When various *object_info() functions are given an extended object info structure as NULL by a caller that does not want any details, the code uses a file-scope static blank_oi and passes it down to the helper functions they use, to avoid handling NULL specifically. The ps/object-read-stream topic graduated to 'master' recently however had a bug that assumed that two identically named file-scope static variables in two functions are the same, which of course is not the case. This made "git commit" take 0.38 seconds to 1508 seconds in some case, as reported by Aaron Plattner here: https://lore.kernel.org/git/f4ba7e89-4717-4b36-921f-56537131fd69@nvidia.com/ We _could_ move the blank_oi variable to the global scope in common section to fix this regression, but explicitly handling the NULL is a much safer fix. It would also reduce the chance of errors that somebody accidentally writes into blank_oi, making its contents dirty, which potentially will make subsequent calls into the function misbehave. By explicitly handling NULL input, we no longer have to worry about it. Reported-by: Aaron Plattner Signed-off-by: Junio C Hamano --- object-file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'object-file.c') diff --git a/object-file.c b/object-file.c index 12177a7dd7..e0cce3a62a 100644 --- a/object-file.c +++ b/object-file.c @@ -426,7 +426,7 @@ int odb_source_loose_read_object_info(struct odb_source *source, unsigned long size_scratch; enum object_type type_scratch; - if (oi->delta_base_oid) + if (oi && oi->delta_base_oid) oidclr(oi->delta_base_oid, source->odb->repo->hash_algo); /* @@ -437,13 +437,13 @@ int odb_source_loose_read_object_info(struct odb_source *source, * return value implicitly indicates whether the * object even exists. */ - if (!oi->typep && !oi->sizep && !oi->contentp) { + if (!oi || (!oi->typep && !oi->sizep && !oi->contentp)) { struct stat st; - if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK)) + if ((!oi || !oi->disk_sizep) && (flags & OBJECT_INFO_QUICK)) return quick_has_loose(source->loose, oid) ? 0 : -1; if (stat_loose_object(source->loose, oid, &st, &path) < 0) return -1; - if (oi->disk_sizep) + if (oi && oi->disk_sizep) *oi->disk_sizep = st.st_size; return 0; } -- cgit v1.3