From: Matthew DeVore <matvore@comcast.net>
To: Jeff King <peff@peff.net>
Cc: Emily Shaffer <emilyshaffer@google.com>,
Matthew DeVore <matvore@google.com>,
jonathantanmy@google.com, jrn@google.com, git@vger.kernel.org,
dstolee@microsoft.com, jeffhost@microsoft.com,
jrnieder@gmail.com, pclouds@gmail.com
Subject: Re: [PATCH v1 3/5] list-objects-filter: implement composite filters
Date: Mon, 3 Jun 2019 15:22:47 -0700 [thread overview]
Message-ID: <20190603222247.GG4641@comcast.net> (raw)
In-Reply-To: <20190603123435.GA18953@sigill.intra.peff.net>
On Mon, Jun 03, 2019 at 08:34:35AM -0400, Jeff King wrote:
> Great. We might want to stop there, but it's possible could reuse even
> more code. I didn't look closely before, but it seems this code is
> decoding a URL. We already have a url_decode() routine in url.c. Could
> it be reused?
Very nice. Here is an interdiff and the changes will be included in v3 of my
patchset:
diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c
index ed02c88eb6..0f135602a7 100644
--- a/list-objects-filter-options.c
+++ b/list-objects-filter-options.c
@@ -1,19 +1,20 @@
#include "cache.h"
#include "commit.h"
#include "config.h"
#include "revision.h"
#include "argv-array.h"
#include "list-objects.h"
#include "list-objects-filter.h"
#include "list-objects-filter-options.h"
#include "trace.h"
+#include "url.h"
static int parse_combine_filter(
struct list_objects_filter_options *filter_options,
const char *arg,
struct strbuf *errbuf);
/*
* Parse value of the argument to the "filter" keyword.
* On the command line this looks like:
* --filter=<arg>
@@ -84,54 +85,20 @@ static int gently_parse_list_objects_filter(
* Please update _git_fetch() in git-completion.bash when you
* add new filters
*/
strbuf_addf(errbuf, "invalid filter-spec '%s'", arg);
memset(filter_options, 0, sizeof(*filter_options));
return 1;
}
-static int url_decode(struct strbuf *s, struct strbuf *errbuf)
-{
- char *dest = s->buf;
- char *src = s->buf;
- size_t new_len;
-
- while (*src) {
- if (src[0] != '%') {
- *dest++ = *src++;
- continue;
- }
-
- if (hex_to_bytes((unsigned char *)dest, src + 1, 1)) {
- strbuf_addstr(errbuf,
- "error in filter-spec - "
- "invalid hex sequence after %");
- return 1;
- }
-
- if (!*dest) {
- strbuf_addstr(errbuf,
- "error in filter-spec - unexpected %00");
- return 1;
- }
-
- src += 3;
- dest++;
- }
- new_len = dest - s->buf;
- strbuf_remove(s, new_len, s->len - new_len);
-
- return 0;
-}
-
static const char *RESERVED_NON_WS = "~`!@#$^&*()[]{}\\;'\",<>?";
static int has_reserved_character(
struct strbuf *sub_spec, struct strbuf *errbuf)
{
const char *c = sub_spec->buf;
while (*c) {
if (*c <= ' ' || strchr(RESERVED_NON_WS, *c)) {
strbuf_addf(errbuf,
"must escape char in sub-filter-spec: '%c'",
@@ -147,56 +114,57 @@ static int has_reserved_character(
static int parse_combine_subfilter(
struct list_objects_filter_options *filter_options,
struct strbuf *subspec,
struct strbuf *errbuf)
{
size_t new_index = filter_options->sub_nr;
ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
filter_options->sub_alloc);
- return has_reserved_character(subspec, errbuf) ||
- url_decode(subspec, errbuf) ||
- gently_parse_list_objects_filter(
- &filter_options->sub[new_index], subspec->buf, errbuf);
+ decoded = url_percent_decode(subspec->buf);
+
+ result = gently_parse_list_objects_filter(
+ &filter_options->sub[new_index], decoded, errbuf);
+
+ free(decoded);
+ return result;
}
static int parse_combine_filter(
struct list_objects_filter_options *filter_options,
const char *arg,
struct strbuf *errbuf)
{
struct strbuf **subspecs = strbuf_split_str(arg, '+', 0);
size_t sub;
- int result;
+ int result = 0;
if (!subspecs[0]) {
strbuf_addf(errbuf,
_("expected something after combine:"));
result = 1;
goto cleanup;
}
- for (sub = 0; subspecs[sub]; sub++) {
+ 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);
- if (result)
- goto cleanup;
}
filter_options->choice = LOFC_COMBINE;
cleanup:
strbuf_list_free(subspecs);
if (result) {
list_objects_filter_release(filter_options);
memset(filter_options, 0, sizeof(*filter_options));
}
diff --git a/t/t6112-rev-list-filters-objects.sh b/t/t6112-rev-list-filters-objects.sh
index 7fb5e50cde..e1bf3ed038 100755
--- a/t/t6112-rev-list-filters-objects.sh
+++ b/t/t6112-rev-list-filters-objects.sh
@@ -405,32 +405,20 @@ test_expect_success 'combine:... while URL-encoding things that should not be' '
test_expect_success 'combine: with nothing after the :' '
expect_invalid_filter_spec combine: "expected something after combine:"
'
test_expect_success 'parse error in first sub-filter in combine:' '
expect_invalid_filter_spec combine:tree:asdf+blob:none \
"expected .tree:<depth>."
'
-test_expect_success 'combine:... with invalid URL-encoded sequences' '
- # Not enough hex chars
- expect_invalid_filter_spec combine:tree:2+blob:non%a \
- "error in filter-spec - invalid hex sequence after %" &&
- # Non-hex digit after %
- expect_invalid_filter_spec combine:tree:2+blob%G5none \
- "error in filter-spec - invalid hex sequence after %" &&
- # Null byte encoded by %
- expect_invalid_filter_spec combine:tree:2+blob%00none \
- "error in filter-spec - unexpected %00"
-'
-
test_expect_success 'combine:... with non-encoded reserved chars' '
expect_invalid_filter_spec combine:tree:2+sparse:@xyz \
"must escape char in sub-filter-spec: .@." &&
expect_invalid_filter_spec combine:tree:2+sparse:\` \
"must escape char in sub-filter-spec: .\`." &&
expect_invalid_filter_spec combine:tree:2+sparse:~abc \
"must escape char in sub-filter-spec: .\~."
'
test_expect_success 'validate err msg for "combine:<valid-filter>+"' '
diff --git a/url.c b/url.c
index 25576c390b..bdede647bc 100644
--- a/url.c
+++ b/url.c
@@ -79,20 +79,26 @@ char *url_decode_mem(const char *url, int len)
/* Skip protocol part if present */
if (colon && url < colon) {
strbuf_add(&out, url, colon - url);
len -= colon - url;
url = colon;
}
return url_decode_internal(&url, len, NULL, &out, 0);
}
+char *url_percent_decode(const char *encoded)
+{
+ struct strbuf out = STRBUF_INIT;
+ return url_decode_internal(&encoded, strlen(encoded), NULL, &out, 0);
+}
+
char *url_decode_parameter_name(const char **query)
{
struct strbuf out = STRBUF_INIT;
return url_decode_internal(query, -1, "&=", &out, 1);
}
char *url_decode_parameter_value(const char **query)
{
struct strbuf out = STRBUF_INIT;
return url_decode_internal(query, -1, "&", &out, 1);
diff --git a/url.h b/url.h
index 00b7d58c33..2a27c34277 100644
--- a/url.h
+++ b/url.h
@@ -1,16 +1,24 @@
#ifndef URL_H
#define URL_H
struct strbuf;
int is_url(const char *url);
int is_urlschemechar(int first_flag, int ch);
char *url_decode(const char *url);
char *url_decode_mem(const char *url, int len);
+
+/*
+ * Similar to the url_decode_{,mem} methods above, but doesn't assume there
+ * is a scheme followed by a : at the start of the string. Instead, %-sequences
+ * before any : are also parsed.
+ */
+char *url_percent_decode(const char *encoded);
+
char *url_decode_parameter_name(const char **query);
char *url_decode_parameter_value(const char **query);
void end_url_with_slash(struct strbuf *buf, const char *url);
void str_end_url_with_slash(const char *url, char **dest);
#endif /* URL_H */
next prev parent reply other threads:[~2019-06-03 22:22 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-22 0:21 [PATCH v1 0/5] Filter combination Matthew DeVore
2019-05-22 0:21 ` [PATCH v1 1/5] list-objects-filter: refactor into a context struct Matthew DeVore
2019-05-24 0:49 ` Emily Shaffer
2019-05-28 18:48 ` Matthew DeVore
2019-05-28 22:40 ` [PATCH] list-objects-filter: merge filter data structs Matthew DeVore
2019-05-29 19:48 ` Junio C Hamano
2019-05-29 20:57 ` Jeff Hostetler
2019-05-29 23:10 ` Matthew DeVore
2019-05-30 1:56 ` [RFC PATCH v2] " Matthew DeVore
2019-05-30 16:12 ` Junio C Hamano
2019-05-30 18:29 ` Matthew DeVore
2019-05-30 19:05 ` [PATCH] " Matthew DeVore
2019-05-22 0:21 ` [PATCH v1 2/5] list-objects-filter-options: error is localizeable Matthew DeVore
2019-05-24 0:55 ` Emily Shaffer
2019-05-28 23:01 ` Matthew DeVore
2019-05-22 0:21 ` [PATCH v1 3/5] list-objects-filter: implement composite filters Matthew DeVore
2019-05-24 21:01 ` Jeff Hostetler
2019-05-28 17:59 ` Junio C Hamano
2019-05-29 15:02 ` Matthew DeVore
2019-05-29 21:29 ` Jeff Hostetler
2019-05-29 23:27 ` Matthew DeVore
2019-05-30 14:01 ` Jeff Hostetler
2019-05-31 20:53 ` Matthew DeVore
2019-06-03 21:04 ` Jeff Hostetler
2019-06-01 0:11 ` Matthew DeVore
2019-05-28 21:53 ` Emily Shaffer
2019-05-31 20:48 ` Matthew DeVore
2019-05-31 21:10 ` Jeff King
2019-06-01 0:12 ` Matthew DeVore
2019-06-03 12:34 ` Jeff King
2019-06-03 22:22 ` Matthew DeVore [this message]
2019-06-04 16:13 ` Jeff King
2019-06-04 17:19 ` Matthew DeVore
2019-06-04 18:51 ` Jeff King
2019-06-04 22:59 ` Matthew DeVore
2019-06-04 23:14 ` Jeff King
2019-06-04 23:49 ` Matthew DeVore
2019-06-09 12:36 ` Jeff King
2019-05-22 0:21 ` [PATCH v1 4/5] list-objects-filter-options: move error check up Matthew DeVore
2019-05-22 0:21 ` [PATCH v1 5/5] list-objects-filter-options: allow mult. --filter Matthew DeVore
2019-06-06 22:44 ` [PATCH v1 0/5] Filter combination Matthew DeVore
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190603222247.GG4641@comcast.net \
--to=matvore@comcast.net \
--cc=dstolee@microsoft.com \
--cc=emilyshaffer@google.com \
--cc=git@vger.kernel.org \
--cc=jeffhost@microsoft.com \
--cc=jonathantanmy@google.com \
--cc=jrn@google.com \
--cc=jrnieder@gmail.com \
--cc=matvore@google.com \
--cc=pclouds@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).