2023-02-24 00:09:34 +00:00
|
|
|
#include "git-compat-util.h"
|
2023-02-24 00:09:27 +00:00
|
|
|
#include "hex.h"
|
2023-02-24 00:09:34 +00:00
|
|
|
#include "strbuf.h"
|
Fix sparse warnings
Fix warnings from 'make check'.
- These files don't include 'builtin.h' causing sparse to complain that
cmd_* isn't declared:
builtin/clone.c:364, builtin/fetch-pack.c:797,
builtin/fmt-merge-msg.c:34, builtin/hash-object.c:78,
builtin/merge-index.c:69, builtin/merge-recursive.c:22
builtin/merge-tree.c:341, builtin/mktag.c:156, builtin/notes.c:426
builtin/notes.c:822, builtin/pack-redundant.c:596,
builtin/pack-refs.c:10, builtin/patch-id.c:60, builtin/patch-id.c:149,
builtin/remote.c:1512, builtin/remote-ext.c:240,
builtin/remote-fd.c:53, builtin/reset.c:236, builtin/send-pack.c:384,
builtin/unpack-file.c:25, builtin/var.c:75
- These files have symbols which should be marked static since they're
only file scope:
submodule.c:12, diff.c:631, replace_object.c:92, submodule.c:13,
submodule.c:14, trace.c:78, transport.c:195, transport-helper.c:79,
unpack-trees.c:19, url.c:3, url.c:18, url.c:104, url.c:117, url.c:123,
url.c:129, url.c:136, thread-utils.c:21, thread-utils.c:48
- These files redeclare symbols to be different types:
builtin/index-pack.c:210, parse-options.c:564, parse-options.c:571,
usage.c:49, usage.c:58, usage.c:63, usage.c:72
- These files use a literal integer 0 when they really should use a NULL
pointer:
daemon.c:663, fast-import.c:2942, imap-send.c:1072, notes-merge.c:362
While we're in the area, clean up some unused #includes in builtin files
(mostly exec_cmd.h).
Signed-off-by: Stephen Boyd <bebarino@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-22 07:51:05 +00:00
|
|
|
#include "url.h"
|
2010-05-23 09:17:55 +00:00
|
|
|
|
|
|
|
int is_urlschemechar(int first_flag, int ch)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* The set of valid URL schemes, as per STD66 (RFC3986) is
|
2019-11-05 17:07:23 +00:00
|
|
|
* '[A-Za-z][A-Za-z0-9+.-]*'. But use slightly looser check
|
2010-05-23 09:17:55 +00:00
|
|
|
* of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
|
|
|
|
* of check used '[A-Za-z0-9]+' so not to break any remote
|
|
|
|
* helpers.
|
|
|
|
*/
|
|
|
|
int alphanumeric, special;
|
|
|
|
alphanumeric = ch > 0 && isalnum(ch);
|
|
|
|
special = ch == '+' || ch == '-' || ch == '.';
|
|
|
|
return alphanumeric || (!first_flag && special);
|
|
|
|
}
|
|
|
|
|
|
|
|
int is_url(const char *url)
|
|
|
|
{
|
2011-10-03 17:56:42 +00:00
|
|
|
/* Is "scheme" part reasonable? */
|
|
|
|
if (!url || !is_urlschemechar(1, *url++))
|
2010-05-23 09:17:55 +00:00
|
|
|
return 0;
|
2011-10-03 17:56:42 +00:00
|
|
|
while (*url && *url != ':') {
|
|
|
|
if (!is_urlschemechar(0, *url++))
|
2010-05-23 09:17:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-10-03 17:56:42 +00:00
|
|
|
/* We've seen "scheme"; we want colon-slash-slash */
|
|
|
|
return (url[0] == ':' && url[1] == '/' && url[2] == '/');
|
2010-05-23 09:17:55 +00:00
|
|
|
}
|
|
|
|
|
2011-07-18 07:48:51 +00:00
|
|
|
static char *url_decode_internal(const char **query, int len,
|
|
|
|
const char *stop_at, struct strbuf *out,
|
|
|
|
int decode_plus)
|
2010-05-23 09:17:55 +00:00
|
|
|
{
|
|
|
|
const char *q = *query;
|
|
|
|
|
2011-07-18 07:48:51 +00:00
|
|
|
while (len) {
|
2010-05-23 09:17:55 +00:00
|
|
|
unsigned char c = *q;
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
break;
|
|
|
|
if (stop_at && strchr(stop_at, c)) {
|
|
|
|
q++;
|
2011-07-18 07:48:51 +00:00
|
|
|
len--;
|
2010-05-23 09:17:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-06-04 17:57:04 +00:00
|
|
|
if (c == '%' && (len < 0 || len >= 3)) {
|
2016-09-03 15:59:20 +00:00
|
|
|
int val = hex2chr(q + 1);
|
2019-06-04 17:57:05 +00:00
|
|
|
if (0 < val) {
|
2010-06-23 17:27:39 +00:00
|
|
|
strbuf_addch(out, val);
|
2010-05-23 09:17:55 +00:00
|
|
|
q += 3;
|
2011-07-18 07:48:51 +00:00
|
|
|
len -= 3;
|
2010-05-23 09:17:55 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-24 14:49:04 +00:00
|
|
|
if (decode_plus && c == '+')
|
2010-06-23 17:27:39 +00:00
|
|
|
strbuf_addch(out, ' ');
|
2010-05-23 09:17:55 +00:00
|
|
|
else
|
2010-06-23 17:27:39 +00:00
|
|
|
strbuf_addch(out, c);
|
2010-05-23 09:17:55 +00:00
|
|
|
q++;
|
2011-07-18 07:48:51 +00:00
|
|
|
len--;
|
|
|
|
}
|
2010-05-23 09:17:55 +00:00
|
|
|
*query = q;
|
2010-06-23 17:27:39 +00:00
|
|
|
return strbuf_detach(out, NULL);
|
2010-05-23 09:17:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *url_decode(const char *url)
|
2011-07-18 07:48:51 +00:00
|
|
|
{
|
|
|
|
return url_decode_mem(url, strlen(url));
|
|
|
|
}
|
|
|
|
|
|
|
|
char *url_decode_mem(const char *url, int len)
|
2010-05-23 09:17:55 +00:00
|
|
|
{
|
2010-06-23 17:27:39 +00:00
|
|
|
struct strbuf out = STRBUF_INIT;
|
2011-07-18 07:48:51 +00:00
|
|
|
const char *colon = memchr(url, ':', len);
|
2010-06-23 17:27:39 +00:00
|
|
|
|
|
|
|
/* Skip protocol part if present */
|
2010-06-24 20:36:30 +00:00
|
|
|
if (colon && url < colon) {
|
|
|
|
strbuf_add(&out, url, colon - url);
|
2011-07-18 07:48:51 +00:00
|
|
|
len -= colon - url;
|
2010-06-24 20:36:30 +00:00
|
|
|
url = colon;
|
2010-06-23 17:27:39 +00:00
|
|
|
}
|
2011-07-18 07:48:51 +00:00
|
|
|
return url_decode_internal(&url, len, NULL, &out, 0);
|
2010-05-23 09:17:55 +00:00
|
|
|
}
|
|
|
|
|
2019-06-27 22:54:08 +00:00
|
|
|
char *url_percent_decode(const char *encoded)
|
|
|
|
{
|
|
|
|
struct strbuf out = STRBUF_INIT;
|
|
|
|
return url_decode_internal(&encoded, strlen(encoded), NULL, &out, 0);
|
|
|
|
}
|
|
|
|
|
2010-05-23 09:17:55 +00:00
|
|
|
char *url_decode_parameter_name(const char **query)
|
|
|
|
{
|
2010-06-23 17:27:39 +00:00
|
|
|
struct strbuf out = STRBUF_INIT;
|
2011-07-18 07:48:51 +00:00
|
|
|
return url_decode_internal(query, -1, "&=", &out, 1);
|
2010-05-23 09:17:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *url_decode_parameter_value(const char **query)
|
|
|
|
{
|
2010-06-23 17:27:39 +00:00
|
|
|
struct strbuf out = STRBUF_INIT;
|
2011-07-18 07:48:51 +00:00
|
|
|
return url_decode_internal(query, -1, "&", &out, 1);
|
2010-05-23 09:17:55 +00:00
|
|
|
}
|
2010-11-25 08:21:04 +00:00
|
|
|
|
|
|
|
void end_url_with_slash(struct strbuf *buf, const char *url)
|
|
|
|
{
|
|
|
|
strbuf_addstr(buf, url);
|
use strbuf_complete to conditionally append slash
When working with paths in strbufs, we frequently want to
ensure that a directory contains a trailing slash before
appending to it. We can shorten this code (and make the
intent more obvious) by calling strbuf_complete.
Most of these cases are trivially identical conversions, but
there are two things to note:
- in a few cases we did not check that the strbuf is
non-empty (which would lead to an out-of-bounds memory
access). These were generally not triggerable in
practice, either from earlier assertions, or typically
because we would have just fed the strbuf to opendir(),
which would choke on an empty path.
- in a few cases we indexed the buffer with "original_len"
or similar, rather than the current sb->len, and it is
not immediately obvious from the diff that they are the
same. In all of these cases, I manually verified that
the strbuf does not change between the assignment and
the strbuf_complete call.
This does not convert cases which look like:
if (sb->len && !is_dir_sep(sb->buf[sb->len - 1]))
strbuf_addch(sb, '/');
as those are obviously semantically different. Some of these
cases arguably should be doing that, but that is out of
scope for this change, which aims purely for cleanup with no
behavior change (and at least it will make such sites easier
to find and examine in the future, as we can grep for
strbuf_complete).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-24 21:08:35 +00:00
|
|
|
strbuf_complete(buf, '/');
|
2010-11-25 08:21:04 +00:00
|
|
|
}
|
2010-11-25 08:21:05 +00:00
|
|
|
|
2018-12-09 10:25:21 +00:00
|
|
|
void str_end_url_with_slash(const char *url, char **dest)
|
|
|
|
{
|
2010-11-25 08:21:05 +00:00
|
|
|
struct strbuf buf = STRBUF_INIT;
|
|
|
|
end_url_with_slash(&buf, url);
|
|
|
|
free(*dest);
|
|
|
|
*dest = strbuf_detach(&buf, NULL);
|
|
|
|
}
|