aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Marks <pmarks@google.com>2014-03-30 07:50:37 +0200
committerDaniel Stenberg <daniel@haxx.se>2014-03-30 23:45:29 +0200
commit0bc4938eecccefdf8906bf9c488e4cd9c8467e99 (patch)
treeb6a82fdddea4cf18dd21ae49cde331435d855425 /src
parent4043d7b67b6d4c03e8c529408edbe65bc66e5ae1 (diff)
curl: stop interpreting IPv6 literals as glob patterns.
This makes it possible to fetch from an IPv6 literal without specifying the -g option. Globbing remains available elsehwere in the URL. For example: curl http://[::1]/file[1-3].txt This creates no ambiguity, because there is no overlap between the syntax of valid globs and valid IPv6 literals. Globs contain hyphens and at most 1 colon, while IPv6 literals have no hyphens, and at least 2 colons. The peek_ipv6() parser simply whitelists a set of characters and counts colons, because the real validation happens later on. The character set includes A-Z, in case someone decides to implement support for scopes like [fe80::1%25eth0] in the future. Signed-off-by: Paul Marks <pmarks@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/tool_urlglob.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c
index ec5014b97..943e0ab88 100644
--- a/src/tool_urlglob.c
+++ b/src/tool_urlglob.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -302,6 +302,36 @@ static GlobCode glob_range(URLGlob *glob, char **patternp,
return GLOB_OK;
}
+static bool peek_ipv6(const char *str, size_t *skip)
+{
+ /*
+ * Scan for a potential IPv6 literal.
+ * - Valid globs contain a hyphen and <= 1 colon.
+ * - IPv6 literals contain no hyphens and >= 2 colons.
+ */
+ size_t i = 0;
+ size_t colons = 0;
+ if(str[i++] != '[') {
+ return FALSE;
+ }
+ for(;;) {
+ const char c = str[i++];
+ if(ISALNUM(c) || c == '.' || c == '%') {
+ /* ok */
+ }
+ else if(c == ':') {
+ colons++;
+ }
+ else if(c == ']') {
+ *skip = i;
+ return colons >= 2;
+ }
+ else {
+ return FALSE;
+ }
+ }
+}
+
static GlobCode glob_parse(URLGlob *glob, char *pattern,
size_t pos, unsigned long *amount)
{
@@ -315,8 +345,20 @@ static GlobCode glob_parse(URLGlob *glob, char *pattern,
while(*pattern && !res) {
char *buf = glob->glob_buffer;
- int sublen = 0;
- while(*pattern && *pattern != '{' && *pattern != '[') {
+ size_t sublen = 0;
+ while(*pattern && *pattern != '{') {
+ if(*pattern == '[') {
+ /* Skip over potential IPv6 literals. */
+ size_t skip;
+ if(peek_ipv6(pattern, &skip)) {
+ memcpy(buf, pattern, skip);
+ buf += skip;
+ pattern += skip;
+ sublen += skip;
+ continue;
+ }
+ break;
+ }
if(*pattern == '}' || *pattern == ']')
return GLOBERROR("unmatched close brace/bracket", pos, GLOB_ERROR);