glob: reduce the number of allocations for URLs that don't need globbing.
No binary (build failed)
—
(log yok)
| @@ -1242,10 +1242,11 @@ static CURLcode setup_input_file(struct OperationConfig *config, | |
| if(!config->globoff && !glob_inuse(&state->inglob)) | |
| result = glob_url(&state->inglob, u->infile, &state->upnum, err); | |
| if(!result && !state->uploadfile) { | |
| - | if(glob_inuse(&state->inglob)) |
| + | if(glob_inuse(&state->inglob) && |
| + | !glob_is_literal(&state->inglob)) |
| result = glob_next_url(&state->uploadfile, &state->inglob); | |
| else if(!state->upidx) { | |
| - | /* copy the allocated string */ |
| + | /* take ownership of the allocated string */ |
| state->uploadfile = u->infile; | |
| u->infile = NULL; | |
| } | |
| @@ -1305,7 +1306,8 @@ static CURLcode select_next_url(struct State *state, | |
| char **url) | |
| { | |
| CURLcode result = CURLE_OK; | |
| - | if(glob_inuse(&state->urlglob)) |
| + | if(glob_inuse(&state->urlglob) && |
| + | !glob_is_literal(&state->urlglob)) |
| result = glob_next_url(url, &state->urlglob); | |
| else if(!state->urlidx) { | |
| *url = curlx_strdup(u->url); | |
| @@ -543,7 +543,13 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, | |
| bool glob_inuse(struct URLGlob *glob) | |
| { | |
| - | return glob->palloc ? TRUE : FALSE; |
| + | /* Both parsed patterns and a literal URL make the glob active. */ |
| + | return (glob->palloc || glob->literal) ? TRUE : FALSE; |
| + | } |
| + | |
| + | bool glob_is_literal(const struct URLGlob *glob) |
| + | { |
| + | return glob->literal; |
| } | |
| /* a glob error has been confirmed, this outputs details about it to the set | |
| @@ -578,6 +584,12 @@ CURLcode glob_url(struct URLGlob *glob, const char *url, curl_off_t *urlnum, | |
| memset(glob, 0, sizeof(struct URLGlob)); | |
| curlx_dyn_init(&glob->buf, MAX_CONFIG_LINE_LENGTH); | |
| + | if(!strpbrk(url, "{}[]")) { |
| + | /* no glob syntax: use the URL as-is instead of parsing a copy of it */ |
| + | glob->literal = TRUE; |
| + | *urlnum = 1; |
| + | return CURLE_OK; |
| + | } |
| glob->pattern = curlx_malloc(2 * sizeof(struct URLPattern)); | |
| if(!glob->pattern) | |
| return CURLE_OUT_OF_MEMORY; | |
| @@ -598,6 +610,8 @@ void glob_cleanup(struct URLGlob *glob) | |
| { | |
| size_t i; | |
| + | glob->literal = FALSE; |
| + | glob->beenhere = 0; |
| if(glob->pattern) { | |
| for(i = 0; i < glob->pnum; i++) { | |
| DEBUGASSERT(glob->pattern[i].type); | |
| @@ -622,6 +636,7 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob) | |
| size_t i; | |
| *globbed = NULL; | |
| + | DEBUGASSERT(!glob->literal); |
| curlx_dyn_reset(&glob->buf); | |
| if(!glob->beenhere) | |
| @@ -65,6 +65,7 @@ struct URLPattern { | |
| struct URLGlob { | |
| struct dynbuf buf; | |
| struct URLPattern *pattern; | |
| + | bool literal; |
| size_t palloc; /* number of pattern entries allocated */ | |
| size_t pnum; /* number of patterns used */ | |
| char beenhere; | |
| @@ -83,5 +84,6 @@ CURLcode glob_match_url(char **output, const char *filename, | |
| SANITIZEcode *sc); | |
| void glob_cleanup(struct URLGlob *glob); | |
| bool glob_inuse(struct URLGlob *glob); | |
| + | bool glob_is_literal(const struct URLGlob *glob); |
| #endif /* HEADER_CURL_TOOL_URLGLOB_H */ | |
| @@ -1964,6 +1964,7 @@ TESTCASES = \ | |
| test2412 \ | |
| test2413 \ | |
| test2414 \ | |
| + | test2415 \ |
| test2429 \ | |
| test2453 \ | |
| \ | |
| @@ -0,0 +1,36 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTP GET |
| + | globbing |
| + | </keywords> |
| + | </info> |
| + | # Server-side |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | http |
| + | </server> |
| + | <name> |
| + | reference a named glob with a literal URL |
| + | </name> |
| + | <command option="no-output"> |
| + | "%HOSTIP:%HTTPPORT/test" -o "somewhere/#%LTfoo%GT" |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <stderr mode="text"> |
| + | curl: (43) no glob exists with this name in position 16: |
| + | somewhere/#%LTfoo%GT |
| + | ^ |
| + | </stderr> |
| + | <errorcode> |
| + | 43 |
| + | </errorcode> |
| + | </verify> |
| + | </testcase> |