@matheusbsbs / matheus-bagliano / commits / 638794cde0
Fork 0

make url-related functions reusable

The is_url function and url percent-decoding functions were static, but are generally useful. Let's make them available to other parts of the code. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 23, 2010 at 05:17 UTC 638794cde08bb785410a92d293969949a1f5a846
5 files changed +134 -105
Makefile
+1
@@ -627,6 +627,7 @@ LIB_OBJS += tree-diff.o
627 LIB_OBJS += tree.o
628 LIB_OBJS += tree-walk.o
629 LIB_OBJS += unpack-trees.o
630 +LIB_OBJS += url.o
631 LIB_OBJS += usage.o
632 LIB_OBJS += userdiff.o
633 LIB_OBJS += utf8.o
http-backend.c
+3 -56
@@ -6,6 +6,7 @@
6 #include "exec_cmd.h"
7 #include "run-command.h"
8 #include "string-list.h"
9 +#include "url.h"
10
11 static const char content_type[] = "Content-Type";
12 static const char content_length[] = "Content-Length";
@@ -25,60 +26,6 @@ static struct rpc_service rpc_service[] = {
26 { "receive-pack", "receivepack", -1 },
27 };
28
28 -static int decode_char(const char *q)
29 -{
30 - int i;
31 - unsigned char val = 0;
32 - for (i = 0; i < 2; i++) {
33 - unsigned char c = *q++;
34 - val <<= 4;
35 - if (c >= '0' && c <= '9')
36 - val += c - '0';
37 - else if (c >= 'a' && c <= 'f')
38 - val += c - 'a' + 10;
39 - else if (c >= 'A' && c <= 'F')
40 - val += c - 'A' + 10;
41 - else
42 - return -1;
43 - }
44 - return val;
45 -}
46 -
47 -static char *decode_parameter(const char **query, int is_name)
48 -{
49 - const char *q = *query;
50 - struct strbuf out;
51 -
52 - strbuf_init(&out, 16);
53 - do {
54 - unsigned char c = *q;
55 -
56 - if (!c)
57 - break;
58 - if (c == '&' || (is_name && c == '=')) {
59 - q++;
60 - break;
61 - }
62 -
63 - if (c == '%') {
64 - int val = decode_char(q + 1);
65 - if (0 <= val) {
66 - strbuf_addch(&out, val);
67 - q += 3;
68 - continue;
69 - }
70 - }
71 -
72 - if (c == '+')
73 - strbuf_addch(&out, ' ');
74 - else
75 - strbuf_addch(&out, c);
76 - q++;
77 - } while (1);
78 - *query = q;
79 - return strbuf_detach(&out, NULL);
80 -}
81 -
29 static struct string_list *get_parameters(void)
30 {
31 if (!query_params) {
@@ -86,8 +33,8 @@ static struct string_list *get_parameters(void)
33
34 query_params = xcalloc(1, sizeof(*query_params));
35 while (query && *query) {
89 - char *name = decode_parameter(&query, 1);
90 - char *value = decode_parameter(&query, 0);
36 + char *name = url_decode_parameter_name(&query);
37 + char *value = url_decode_parameter_value(&query);
38 struct string_list_item *i;
39
40 i = string_list_lookup(name, query_params);
transport.c
+2 -49
@@ -9,6 +9,7 @@
9 #include "dir.h"
10 #include "refs.h"
11 #include "branch.h"
12 +#include "url.h"
13
14 /* rsync support */
15
@@ -871,54 +872,6 @@ static int is_file(const char *url)
872 return S_ISREG(buf.st_mode);
873 }
874
874 -static int isurlschemechar(int first_flag, int ch)
875 -{
876 - /*
877 - * The set of valid URL schemes, as per STD66 (RFC3986) is
878 - * '[A-Za-z][A-Za-z0-9+.-]*'. But use sightly looser check
879 - * of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
880 - * of check used '[A-Za-z0-9]+' so not to break any remote
881 - * helpers.
882 - */
883 - int alphanumeric, special;
884 - alphanumeric = ch > 0 && isalnum(ch);
885 - special = ch == '+' || ch == '-' || ch == '.';
886 - return alphanumeric || (!first_flag && special);
887 -}
888 -
889 -static int is_url(const char *url)
890 -{
891 - const char *url2, *first_slash;
892 -
893 - if (!url)
894 - return 0;
895 - url2 = url;
896 - first_slash = strchr(url, '/');
897 -
898 - /* Input with no slash at all or slash first can't be URL. */
899 - if (!first_slash || first_slash == url)
900 - return 0;
901 - /* Character before must be : and next must be /. */
902 - if (first_slash[-1] != ':' || first_slash[1] != '/')
903 - return 0;
904 - /* There must be something before the :// */
905 - if (first_slash == url + 1)
906 - return 0;
907 - /*
908 - * Check all characters up to first slash - 1. Only alphanum
909 - * is allowed.
910 - */
911 - url2 = url;
912 - while (url2 < first_slash - 1) {
913 - if (!isurlschemechar(url2 == url, (unsigned char)*url2))
914 - return 0;
915 - url2++;
916 - }
917 -
918 - /* Valid enough. */
919 - return 1;
920 -}
921 -
875 static int external_specification_len(const char *url)
876 {
877 return strchr(url, ':') - url;
@@ -946,7 +899,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
899 if (url) {
900 const char *p = url;
901
949 - while (isurlschemechar(p == url, *p))
902 + while (is_urlschemechar(p == url, *p))
903 p++;
904 if (!prefixcmp(p, "::"))
905 helper = xstrndup(url, p - url);
url.c new
+118
@@ -0,0 +1,118 @@
1 +#include "cache.h"
2 +
3 +int is_urlschemechar(int first_flag, int ch)
4 +{
5 + /*
6 + * The set of valid URL schemes, as per STD66 (RFC3986) is
7 + * '[A-Za-z][A-Za-z0-9+.-]*'. But use sightly looser check
8 + * of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
9 + * of check used '[A-Za-z0-9]+' so not to break any remote
10 + * helpers.
11 + */
12 + int alphanumeric, special;
13 + alphanumeric = ch > 0 && isalnum(ch);
14 + special = ch == '+' || ch == '-' || ch == '.';
15 + return alphanumeric || (!first_flag && special);
16 +}
17 +
18 +int is_url(const char *url)
19 +{
20 + const char *url2, *first_slash;
21 +
22 + if (!url)
23 + return 0;
24 + url2 = url;
25 + first_slash = strchr(url, '/');
26 +
27 + /* Input with no slash at all or slash first can't be URL. */
28 + if (!first_slash || first_slash == url)
29 + return 0;
30 + /* Character before must be : and next must be /. */
31 + if (first_slash[-1] != ':' || first_slash[1] != '/')
32 + return 0;
33 + /* There must be something before the :// */
34 + if (first_slash == url + 1)
35 + return 0;
36 + /*
37 + * Check all characters up to first slash - 1. Only alphanum
38 + * is allowed.
39 + */
40 + url2 = url;
41 + while (url2 < first_slash - 1) {
42 + if (!is_urlschemechar(url2 == url, (unsigned char)*url2))
43 + return 0;
44 + url2++;
45 + }
46 +
47 + /* Valid enough. */
48 + return 1;
49 +}
50 +
51 +static int url_decode_char(const char *q)
52 +{
53 + int i;
54 + unsigned char val = 0;
55 + for (i = 0; i < 2; i++) {
56 + unsigned char c = *q++;
57 + val <<= 4;
58 + if (c >= '0' && c <= '9')
59 + val += c - '0';
60 + else if (c >= 'a' && c <= 'f')
61 + val += c - 'a' + 10;
62 + else if (c >= 'A' && c <= 'F')
63 + val += c - 'A' + 10;
64 + else
65 + return -1;
66 + }
67 + return val;
68 +}
69 +
70 +static char *url_decode_internal(const char **query, const char *stop_at)
71 +{
72 + const char *q = *query;
73 + struct strbuf out;
74 +
75 + strbuf_init(&out, 16);
76 + do {
77 + unsigned char c = *q;
78 +
79 + if (!c)
80 + break;
81 + if (stop_at && strchr(stop_at, c)) {
82 + q++;
83 + break;
84 + }
85 +
86 + if (c == '%') {
87 + int val = url_decode_char(q + 1);
88 + if (0 <= val) {
89 + strbuf_addch(&out, val);
90 + q += 3;
91 + continue;
92 + }
93 + }
94 +
95 + if (c == '+')
96 + strbuf_addch(&out, ' ');
97 + else
98 + strbuf_addch(&out, c);
99 + q++;
100 + } while (1);
101 + *query = q;
102 + return strbuf_detach(&out, NULL);
103 +}
104 +
105 +char *url_decode(const char *url)
106 +{
107 + return url_decode_internal(&url, NULL);
108 +}
109 +
110 +char *url_decode_parameter_name(const char **query)
111 +{
112 + return url_decode_internal(query, "&=");
113 +}
114 +
115 +char *url_decode_parameter_value(const char **query)
116 +{
117 + return url_decode_internal(query, "&");
118 +}
url.h new
+10
@@ -0,0 +1,10 @@
1 +#ifndef URL_H
2 +#define URL_H
3 +
4 +extern int is_url(const char *url);
5 +extern int is_urlschemechar(int first_flag, int ch);
6 +extern char *url_decode(const char *url);
7 +extern char *url_decode_parameter_name(const char **query);
8 +extern char *url_decode_parameter_value(const char **query);
9 +
10 +#endif /* URL_H */