summaryrefslogtreecommitdiff
path: root/list-objects-filter.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2019-09-15 16:12:44 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-09-16 19:47:37 (GMT)
commit4c96a775945d0299e39b982ab9cb32c5132e877d (patch)
tree09541d4d324ac9f977a1936166918d7eb53d6912 /list-objects-filter.c
parent72de5895ed4d84ad23bd29e48ec613c9117e7117 (diff)
downloadgit-4c96a775945d0299e39b982ab9cb32c5132e877d.zip
git-4c96a775945d0299e39b982ab9cb32c5132e877d.tar.gz
git-4c96a775945d0299e39b982ab9cb32c5132e877d.tar.bz2
list-objects-filter: delay parsing of sparse oid
The list-objects-filter code has two steps to its initialization: 1. parse_list_objects_filter() makes sure the spec is a filter we know about and is syntactically correct. This step is done by "rev-list" or "upload-pack" that is going to apply a filter, but also by "git clone" or "git fetch" before they send the spec across the wire. 2. list_objects_filter__init() runs the type-specific initialization (using function pointers established in step 1). This happens at the start of traverse_commit_list_filtered(), when we're about to actually use the filter. It's a good idea to parse as much as we can in step 1, in order to catch problems early (e.g., a blob size limit that isn't a number). But one thing we _shouldn't_ do is resolve any oids at that step (e.g., for sparse-file contents specified by oid). In the case of a fetch, the oid has to be resolved on the remote side. The current code does resolve the oid during the parse phase, but ignores any error (which we must do, because we might just be sending the spec across the wire). This leads to two bugs: - if we're not in a repository (e.g., because it's git-clone parsing the spec), then we trigger a BUG() trying to resolve the name - if we did hit the error case, we still have to notice that later and bail. The code path in rev-list handles this, but the one in upload-pack does not, leading to a segfault. We can fix both by moving the oid resolution into the sparse-oid init function. At that point we know we have a repository (because we're about to traverse), and handling the error there fixes the segfault. As a bonus, we can drop the NULL sparse_oid_value check in rev-list, since this is now handled in the sparse-oid-filter init function. Signed-off-by: Jeff King <peff@peff.net> Acked-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'list-objects-filter.c')
-rw-r--r--list-objects-filter.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/list-objects-filter.c b/list-objects-filter.c
index 36e1f77..d2cdc03 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -463,9 +463,16 @@ static void *filter_sparse_oid__init(
filter_free_fn *filter_free_fn)
{
struct filter_sparse_data *d = xcalloc(1, sizeof(*d));
+ struct object_context oc;
+ struct object_id sparse_oid;
+
+ if (get_oid_with_context(the_repository,
+ filter_options->sparse_oid_name,
+ GET_OID_BLOB, &sparse_oid, &oc))
+ die("unable to access sparse blob in '%s'",
+ filter_options->sparse_oid_name);
d->omits = omitted;
- if (add_excludes_from_blob_to_list(filter_options->sparse_oid_value,
- NULL, 0, &d->el) < 0)
+ if (add_excludes_from_blob_to_list(&sparse_oid, NULL, 0, &d->el) < 0)
die("could not load filter specification");
ALLOC_GROW(d->array_frame, d->nr + 1, d->alloc);