aboutsummaryrefslogtreecommitdiff
path: root/list-objects-filter-options.c
diff options
context:
space:
mode:
authorDeveshi Dwivedi <deveshigurgaon@gmail.com>2026-03-11 17:33:36 +0000
committerJunio C Hamano <gitster@pobox.com>2026-03-11 11:08:53 -0700
commitf21967e5415673824d501b318a252c6e8a91d6fb (patch)
treea046b36e90e1ca37dba24bc77f9cd650b12d2c94 /list-objects-filter-options.c
parent4107c0bb3455905aeacdba3be09b20e62b310eaa (diff)
downloadgit-f21967e5415673824d501b318a252c6e8a91d6fb.tar.xz
list-objects-filter-options: avoid strbuf_split_str()
parse_combine_filter() splits a combine: filter spec at '+' using strbuf_split_str(), which yields an array of strbufs with the delimiter left at the end of each non-final piece. The code then mutates each non-final piece to strip the trailing '+' before parsing. Allocating an array of strbufs is unnecessary. The function processes one sub-spec at a time and does not use strbuf editing on the pieces. The two helpers it calls, has_reserved_character() and parse_combine_subfilter(), only read the string content of the strbuf they receive. Walk the input string directly with strchrnul() to find each '+', copying each sub-spec into a reusable temporary buffer. The '+' delimiter is naturally excluded. Empty sub-specs (e.g. from a trailing '+') are silently skipped for consistency. Change the helpers to take const char * instead of struct strbuf *. The test that expected an error on a trailing '+' is removed, since that behavior was incorrect. Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'list-objects-filter-options.c')
-rw-r--r--list-objects-filter-options.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c
index 7f3e7b8f50..cef67e5919 100644
--- a/list-objects-filter-options.c
+++ b/list-objects-filter-options.c
@@ -125,9 +125,9 @@ int gently_parse_list_objects_filter(
static const char *RESERVED_NON_WS = "~`!@#$^&*()[]{}\\;'\",<>?";
static int has_reserved_character(
- struct strbuf *sub_spec, struct strbuf *errbuf)
+ const char *sub_spec, struct strbuf *errbuf)
{
- const char *c = sub_spec->buf;
+ const char *c = sub_spec;
while (*c) {
if (*c <= ' ' || strchr(RESERVED_NON_WS, *c)) {
strbuf_addf(
@@ -144,7 +144,7 @@ static int has_reserved_character(
static int parse_combine_subfilter(
struct list_objects_filter_options *filter_options,
- struct strbuf *subspec,
+ const char *subspec,
struct strbuf *errbuf)
{
size_t new_index = filter_options->sub_nr;
@@ -155,7 +155,7 @@ static int parse_combine_subfilter(
filter_options->sub_alloc);
list_objects_filter_init(&filter_options->sub[new_index]);
- decoded = url_percent_decode(subspec->buf);
+ decoded = url_percent_decode(subspec);
result = has_reserved_character(subspec, errbuf);
if (result)
@@ -182,34 +182,34 @@ static int parse_combine_filter(
const char *arg,
struct strbuf *errbuf)
{
- struct strbuf **subspecs = strbuf_split_str(arg, '+', 0);
- size_t sub;
+ const char *p = arg;
+ struct strbuf sub = STRBUF_INIT;
int result = 0;
- if (!subspecs[0]) {
+ if (!*p) {
strbuf_addstr(errbuf, _("expected something after combine:"));
result = 1;
goto cleanup;
}
- for (sub = 0; subspecs[sub] && !result; sub++) {
- if (subspecs[sub + 1]) {
- /*
- * This is not the last subspec. Remove trailing "+" so
- * we can parse it.
- */
- size_t last = subspecs[sub]->len - 1;
- assert(subspecs[sub]->buf[last] == '+');
- strbuf_remove(subspecs[sub], last, 1);
- }
- result = parse_combine_subfilter(
- filter_options, subspecs[sub], errbuf);
+ while (*p && !result) {
+ const char *end = strchrnul(p, '+');
+
+ strbuf_reset(&sub);
+ strbuf_add(&sub, p, end - p);
+
+ if (sub.len)
+ result = parse_combine_subfilter(filter_options, sub.buf, errbuf);
+
+ if (!*end)
+ break;
+ p = end + 1;
}
+ strbuf_release(&sub);
filter_options->choice = LOFC_COMBINE;
cleanup:
- strbuf_list_free(subspecs);
if (result)
list_objects_filter_release(filter_options);
return result;