diff options
Diffstat (limited to 'external/libcurl_android/jni/libcurl/src/tool_urlglob.c')
-rwxr-xr-x | external/libcurl_android/jni/libcurl/src/tool_urlglob.c | 674 |
1 files changed, 0 insertions, 674 deletions
diff --git a/external/libcurl_android/jni/libcurl/src/tool_urlglob.c b/external/libcurl_android/jni/libcurl/src/tool_urlglob.c deleted file mode 100755 index 36e83c33..00000000 --- a/external/libcurl_android/jni/libcurl/src/tool_urlglob.c +++ /dev/null @@ -1,674 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * 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 - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "tool_setup.h" - -#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */ -#include <curl/mprintf.h> - -#include "tool_urlglob.h" -#include "tool_vms.h" - -#include "memdebug.h" /* keep this as LAST include */ - -typedef enum { - GLOB_OK, - GLOB_NO_MEM = CURLE_OUT_OF_MEMORY, - GLOB_ERROR = CURLE_URL_MALFORMAT -} GlobCode; - -#define GLOBERROR(string, column, code) \ - glob->error = string, glob->pos = column, code - -void glob_cleanup(URLGlob* glob); - -static GlobCode glob_fixed(URLGlob *glob, char *fixed, size_t len) -{ - URLPattern *pat = &glob->pattern[glob->size]; - pat->type = UPTSet; - pat->content.Set.size = 1; - pat->content.Set.ptr_s = 0; - pat->globindex = -1; - - pat->content.Set.elements = malloc(sizeof(char*)); - - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, GLOB_NO_MEM); - - pat->content.Set.elements[0] = malloc(len+1); - if(!pat->content.Set.elements[0]) - return GLOBERROR("out of memory", 0, GLOB_NO_MEM); - - memcpy(pat->content.Set.elements[0], fixed, len); - pat->content.Set.elements[0][len] = 0; - - return GLOB_OK; -} - -/* multiply - * - * Multiplies and checks for overflow. - */ -static int multiply(unsigned long *amount, long with) -{ - unsigned long sum = *amount * with; - if(sum/with != *amount) - return 1; /* didn't fit, bail out */ - *amount = sum; - return 0; -} - -static GlobCode glob_set(URLGlob *glob, char **patternp, - size_t *posp, unsigned long *amount, - int globindex) -{ - /* processes a set expression with the point behind the opening '{' - ','-separated elements are collected until the next closing '}' - */ - URLPattern *pat; - bool done = FALSE; - char *buf = glob->glob_buffer; - char *pattern = *patternp; - char *opattern = pattern; - size_t opos = *posp-1; - - pat = &glob->pattern[glob->size]; - /* patterns 0,1,2,... correspond to size=1,3,5,... */ - pat->type = UPTSet; - pat->content.Set.size = 0; - pat->content.Set.ptr_s = 0; - pat->content.Set.elements = NULL; - pat->globindex = globindex; - - while(!done) { - switch (*pattern) { - case '\0': /* URL ended while set was still open */ - return GLOBERROR("unmatched brace", opos, GLOB_ERROR); - - case '{': - case '[': /* no nested expressions at this time */ - return GLOBERROR("nested brace", *posp, GLOB_ERROR); - - case '}': /* set element completed */ - if(opattern == pattern) - return GLOBERROR("empty string within braces", *posp, GLOB_ERROR); - - /* add 1 to size since it'll be incremented below */ - if(multiply(amount, pat->content.Set.size+1)) - return GLOBERROR("range overflow", 0, GLOB_ERROR); - - /* fall-through */ - case ',': - - *buf = '\0'; - if(pat->content.Set.elements) { - char **new_arr = realloc(pat->content.Set.elements, - (pat->content.Set.size + 1) * sizeof(char*)); - if(!new_arr) - return GLOBERROR("out of memory", 0, GLOB_NO_MEM); - - pat->content.Set.elements = new_arr; - } - else - pat->content.Set.elements = malloc(sizeof(char*)); - - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, GLOB_NO_MEM); - - pat->content.Set.elements[pat->content.Set.size] = - strdup(glob->glob_buffer); - if(!pat->content.Set.elements[pat->content.Set.size]) - return GLOBERROR("out of memory", 0, GLOB_NO_MEM); - ++pat->content.Set.size; - - if(*pattern == '}') { - pattern++; /* pass the closing brace */ - done = TRUE; - continue; - } - - buf = glob->glob_buffer; - ++pattern; - ++(*posp); - break; - - case ']': /* illegal closing bracket */ - return GLOBERROR("unexpected close bracket", *posp, GLOB_ERROR); - - case '\\': /* escaped character, skip '\' */ - if(pattern[1]) { - ++pattern; - ++(*posp); - } - /* intentional fallthrough */ - default: - *buf++ = *pattern++; /* copy character to set element */ - ++(*posp); - } - } - - *patternp = pattern; /* return with the new position */ - return GLOB_OK; -} - -static GlobCode glob_range(URLGlob *glob, char **patternp, - size_t *posp, unsigned long *amount, - int globindex) -{ - /* processes a range expression with the point behind the opening '[' - - char range: e.g. "a-z]", "B-Q]" - - num range: e.g. "0-9]", "17-2000]" - - num range with leading zeros: e.g. "001-999]" - expression is checked for well-formedness and collected until the next ']' - */ - URLPattern *pat; - int rc; - char *pattern = *patternp; - char *c; - - pat = &glob->pattern[glob->size]; - pat->globindex = globindex; - - if(ISALPHA(*pattern)) { - /* character range detected */ - char min_c; - char max_c; - int step=1; - - pat->type = UPTCharRange; - - rc = sscanf(pattern, "%c-%c", &min_c, &max_c); - - if((rc == 2) && (pattern[3] == ':')) { - char *endp; - unsigned long lstep; - errno = 0; - lstep = strtoul(&pattern[3], &endp, 10); - if(errno || (*endp != ']')) - step = -1; - else { - pattern = endp+1; - step = (int)lstep; - if(step > (max_c - min_c)) - step = -1; - } - } - else - pattern += 4; - - *posp += (pattern - *patternp); - - if((rc != 2) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) || - (step < 0) ) - /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, GLOB_ERROR); - - /* if there was a ":[num]" thing, use that as step or else use 1 */ - pat->content.CharRange.step = step; - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c; - pat->content.CharRange.max_c = max_c; - - if(multiply(amount, (pat->content.CharRange.max_c - - pat->content.CharRange.min_c + 1))) - return GLOBERROR("range overflow", *posp, GLOB_ERROR); - } - else if(ISDIGIT(*pattern)) { - /* numeric range detected */ - unsigned long min_n; - unsigned long max_n = 0; - unsigned long step_n = 0; - char *endp; - - pat->type = UPTNumRange; - pat->content.NumRange.padlength = 0; - - if(*pattern == '0') { - /* leading zero specified, count them! */ - c = pattern; - while(ISDIGIT(*c)) { - c++; - ++pat->content.NumRange.padlength; /* padding length is set for all - instances of this pattern */ - } - } - - errno = 0; - min_n = strtoul(pattern, &endp, 10); - if(errno || (endp == pattern)) - endp=NULL; - else { - if(*endp != '-') - endp = NULL; - else { - pattern = endp+1; - errno = 0; - max_n = strtoul(pattern, &endp, 10); - if(errno || (*endp == ':')) { - pattern = endp+1; - errno = 0; - step_n = strtoul(pattern, &endp, 10); - if(errno) - /* over/underflow situation */ - endp = NULL; - } - else - step_n = 1; - if(endp && (*endp == ']')) { - pattern= endp+1; - } - else - endp = NULL; - } - } - - *posp += (pattern - *patternp); - - if(!endp || (min_n > max_n) || (step_n > (max_n - min_n))) - /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, GLOB_ERROR); - - /* typecasting to ints are fine here since we make sure above that we - are within 31 bits */ - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n; - pat->content.NumRange.max_n = max_n; - pat->content.NumRange.step = step_n; - - if(multiply(amount, (pat->content.NumRange.max_n - - pat->content.NumRange.min_n + 1))) - return GLOBERROR("range overflow", *posp, GLOB_ERROR); - } - else - return GLOBERROR("bad range specification", *posp, GLOB_ERROR); - - *patternp = pattern; - 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 ? TRUE : FALSE; - } - else { - return FALSE; - } - } -} - -static GlobCode glob_parse(URLGlob *glob, char *pattern, - size_t pos, unsigned long *amount) -{ - /* processes a literal string component of a URL - special characters '{' and '[' branch to set/range processing functions - */ - GlobCode res = GLOB_OK; - int globindex = 0; /* count "actual" globs */ - - *amount = 1; - - while(*pattern && !res) { - char *buf = glob->glob_buffer; - 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); - - /* only allow \ to escape known "special letters" */ - if(*pattern == '\\' && - (*(pattern+1) == '{' || *(pattern+1) == '[' || - *(pattern+1) == '}' || *(pattern+1) == ']') ) { - - /* escape character, skip '\' */ - ++pattern; - ++pos; - } - *buf++ = *pattern++; /* copy character to literal */ - ++pos; - sublen++; - } - if(sublen) { - /* we got a literal string, add it as a single-item list */ - *buf = '\0'; - res = glob_fixed(glob, glob->glob_buffer, sublen); - } - else { - switch (*pattern) { - case '\0': /* done */ - break; - - case '{': - /* process set pattern */ - pattern++; - pos++; - res = glob_set(glob, &pattern, &pos, amount, globindex++); - break; - - case '[': - /* process range pattern */ - pattern++; - pos++; - res = glob_range(glob, &pattern, &pos, amount, globindex++); - break; - } - } - - if(++glob->size > GLOB_PATTERN_NUM) - return GLOBERROR("too many globs", pos, GLOB_ERROR); - } - return res; -} - -int glob_url(URLGlob** glob, char* url, unsigned long *urlnum, FILE *error) -{ - /* - * We can deal with any-size, just make a buffer with the same length - * as the specified URL! - */ - URLGlob *glob_expand; - unsigned long amount = 0; - char *glob_buffer; - GlobCode res; - - *glob = NULL; - - glob_buffer = malloc(strlen(url) + 1); - if(!glob_buffer) - return CURLE_OUT_OF_MEMORY; - - glob_expand = calloc(1, sizeof(URLGlob)); - if(!glob_expand) { - Curl_safefree(glob_buffer); - return CURLE_OUT_OF_MEMORY; - } - glob_expand->urllen = strlen(url); - glob_expand->glob_buffer = glob_buffer; - - res = glob_parse(glob_expand, url, 1, &amount); - if(!res) - *urlnum = amount; - else { - if(error && glob_expand->error) { - char text[128]; - const char *t; - if(glob_expand->pos) { - snprintf(text, sizeof(text), "%s in column %zu", glob_expand->error, - glob_expand->pos); - t = text; - } - else - t = glob_expand->error; - - /* send error description to the error-stream */ - fprintf(error, "curl: (%d) [globbing] %s\n", res, t); - } - /* it failed, we cleanup */ - glob_cleanup(glob_expand); - *urlnum = 1; - return res; - } - - *glob = glob_expand; - return CURLE_OK; -} - -void glob_cleanup(URLGlob* glob) -{ - size_t i; - int elem; - - /* the < condition is required since i underflows! */ - for(i = glob->size - 1; i < glob->size; --i) { - if((glob->pattern[i].type == UPTSet) && - (glob->pattern[i].content.Set.elements)) { - for(elem = glob->pattern[i].content.Set.size - 1; - elem >= 0; - --elem) { - Curl_safefree(glob->pattern[i].content.Set.elements[elem]); - } - Curl_safefree(glob->pattern[i].content.Set.elements); - } - } - Curl_safefree(glob->glob_buffer); - Curl_safefree(glob); -} - -int glob_next_url(char **globbed, URLGlob *glob) -{ - URLPattern *pat; - size_t i; - size_t j; - size_t len; - size_t buflen = glob->urllen + 1; - char *buf = glob->glob_buffer; - - *globbed = NULL; - - if(!glob->beenhere) - glob->beenhere = 1; - else { - bool carry = TRUE; - - /* implement a counter over the index ranges of all patterns, - starting with the rightmost pattern */ - /* the < condition is required since i underflows! */ - for(i = glob->size - 1; carry && (i < glob->size); --i) { - carry = FALSE; - pat = &glob->pattern[i]; - switch (pat->type) { - case UPTSet: - if((pat->content.Set.elements) && - (++pat->content.Set.ptr_s == pat->content.Set.size)) { - pat->content.Set.ptr_s = 0; - carry = TRUE; - } - break; - case UPTCharRange: - pat->content.CharRange.ptr_c = (char)(pat->content.CharRange.step + - (int)((unsigned char)pat->content.CharRange.ptr_c)); - if(pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) { - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; - carry = TRUE; - } - break; - case UPTNumRange: - pat->content.NumRange.ptr_n += pat->content.NumRange.step; - if(pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) { - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; - carry = TRUE; - } - break; - default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); - return CURLE_FAILED_INIT; - } - } - if(carry) { /* first pattern ptr has run into overflow, done! */ - /* TODO: verify if this should actally return CURLE_OK. */ - return CURLE_OK; /* CURLE_OK to match previous behavior */ - } - } - - for(j = 0; j < glob->size; ++j) { - pat = &glob->pattern[j]; - switch(pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - len = strlen(pat->content.Set.elements[pat->content.Set.ptr_s]); - snprintf(buf, buflen, "%s", - pat->content.Set.elements[pat->content.Set.ptr_s]); - buf += len; - buflen -= len; - } - break; - case UPTCharRange: - *buf++ = pat->content.CharRange.ptr_c; - break; - case UPTNumRange: - len = snprintf(buf, buflen, "%0*ld", - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - buf += len; - buflen -= len; - break; - default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); - return CURLE_FAILED_INIT; - } - } - *buf = '\0'; - - *globbed = strdup(glob->glob_buffer); - if(!*globbed) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -int glob_match_url(char **result, char *filename, URLGlob *glob) -{ - char *target; - size_t allocsize; - char numbuf[18]; - char *appendthis = NULL; - size_t appendlen = 0; - size_t stringlen = 0; - - *result = NULL; - - /* We cannot use the glob_buffer for storage here since the filename may - * be longer than the URL we use. We allocate a good start size, then - * we need to realloc in case of need. - */ - allocsize = strlen(filename) + 1; /* make it at least one byte to store the - trailing zero */ - target = malloc(allocsize); - if(!target) - return CURLE_OUT_OF_MEMORY; - - while(*filename) { - if(*filename == '#' && ISDIGIT(filename[1])) { - unsigned long i; - char *ptr = filename; - unsigned long num = strtoul(&filename[1], &filename, 10); - URLPattern *pat =NULL; - - if(num < glob->size) { - num--; /* make it zero based */ - /* find the correct glob entry */ - for(i=0; i<glob->size; i++) { - if(glob->pattern[i].globindex == (int)num) { - pat = &glob->pattern[i]; - break; - } - } - } - - if(pat) { - switch (pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - appendthis = pat->content.Set.elements[pat->content.Set.ptr_s]; - appendlen = - strlen(pat->content.Set.elements[pat->content.Set.ptr_s]); - } - break; - case UPTCharRange: - numbuf[0] = pat->content.CharRange.ptr_c; - numbuf[1] = 0; - appendthis = numbuf; - appendlen = 1; - break; - case UPTNumRange: - snprintf(numbuf, sizeof(numbuf), "%0*d", - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - appendthis = numbuf; - appendlen = strlen(numbuf); - break; - default: - fprintf(stderr, "internal error: invalid pattern type (%d)\n", - (int)pat->type); - Curl_safefree(target); - return CURLE_FAILED_INIT; - } - } - else { - /* #[num] out of range, use the #[num] in the output */ - filename = ptr; - appendthis = filename++; - appendlen = 1; - } - } - else { - appendthis = filename++; - appendlen = 1; - } - if(appendlen + stringlen >= allocsize) { - char *newstr; - /* we append a single byte to allow for the trailing byte to be appended - at the end of this function outside the while() loop */ - allocsize = (appendlen + stringlen) * 2; - newstr = realloc(target, allocsize + 1); - if(!newstr) { - Curl_safefree(target); - return CURLE_OUT_OF_MEMORY; - } - target = newstr; - } - memcpy(&target[stringlen], appendthis, appendlen); - stringlen += appendlen; - } - target[stringlen]= '\0'; - *result = target; - return CURLE_OK; -} - |