ftp: URL encode file names when wildcarding
No binary (build failed)
—
(log yok)
| @@ -4083,8 +4083,13 @@ static CURLcode wc_statemach(struct Curl_easy *data, | |
| /* filelist has at least one file, lets get first one */ | |
| struct Curl_llist_node *head = Curl_llist_head(&wildcard->filelist); | |
| struct curl_fileinfo *finfo = Curl_node_elem(head); | |
| + | char *tmp_path; |
| + | char *enc = curl_easy_escape(NULL, finfo->filename, 0); |
| + | if(!enc) |
| + | return CURLE_OUT_OF_MEMORY; |
| - | char *tmp_path = curl_maprintf("%s%s", wildcard->path, finfo->filename); |
| + | tmp_path = curl_maprintf("%s%s", wildcard->path, enc); |
| + | curl_free(enc); |
| if(!tmp_path) | |
| return CURLE_OUT_OF_MEMORY; | |
| @@ -2009,6 +2009,7 @@ TESTCASES = \ | |
| test2721 \ | |
| test2722 \ | |
| test2723 \ | |
| + | test2805 \ |
| test2885 \ | |
| test3000 \ | |
| test3001 \ | |
| @@ -0,0 +1,60 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | FTP |
| + | LIST |
| + | wildcardmatch |
| + | ftplistparser |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Directory content is generated by the ftp server itself |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | ftp |
| + | </server> |
| + | <tool> |
| + | lib%TESTNUMBER |
| + | </tool> |
| + | <name> |
| + | FTP wildcards with percent sign in file name |
| + | </name> |
| + | <command> |
| + | ftp://%HOSTIP:%FTPPORT/fully_simulated/percen%74/*.txt |
| + | </command> |
| + | </client> |
| + | |
| + | ############################################ |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <errorcode> |
| + | 0 |
| + | </errorcode> |
| + | |
| + | <protocol crlf="yes"> |
| + | USER anonymous |
| + | PASS [email protected] |
| + | PWD |
| + | CWD fully_simulated |
| + | CWD percent |
| + | EPSV |
| + | TYPE A |
| + | LIST |
| + | EPSV |
| + | TYPE I |
| + | RETR someothertext.txt |
| + | EPSV |
| + | RETR some%2etxt |
| + | QUIT |
| + | </protocol> |
| + | <stdout> |
| + | match: 'someothertext.txt' against pattern '*.txt' |
| + | match: 'some%2etxt' against pattern '*.txt' |
| + | Some junk ;-) This file does not really exist. |
| + | percent in file name. |
| + | </stdout> |
| + | </verify> |
| + | </testcase> |
| @@ -179,7 +179,20 @@ my %file_someothertext_txt = ( | |
| 'perm' => "rw-r--r--" | |
| ); | |
| + | my %file_percent_txt = ( |
| + | 'name' => "some%2etxt", |
| + | 'content' => "percent in file name.\n", |
| + | 'time' => "Apr 17 11:01", |
| + | 'dostime' => "04-17-10 11:01AM", |
| + | 'perm' => "rw-r--r--" |
| + | ); |
| + | |
| my %lists = ( | |
| + | '/fully_simulated/percent/' => { |
| + | 'files' => [ \%file_someothertext_txt, \%file_percent_txt], |
| + | 'eol' => "\r\n", |
| + | 'type' => "unix" |
| + | }, |
| '/fully_simulated/' => { | |
| 'files' => [ \%dir_dot, \%dir_ddot, \%dir_DOS, \%dir_UNIX ], | |
| 'eol' => "\r\n", | |
| @@ -2115,6 +2115,7 @@ sub LIST_ftp { | |
| my @ftpdir = ftp_contentlist($ftptargetdir); | |
| # old hard-coded style | |
| for(@ftpdir) { | |
| + | logmsg "LIST: $_"; |
| senddata $_; | |
| } | |
| } | |
| @@ -313,6 +313,7 @@ TESTS_C = \ | |
| lib2505.c \ | |
| lib2506.c \ | |
| lib2700.c \ | |
| + | lib2805.c \ |
| lib3010.c \ | |
| lib3025.c \ | |
| lib3026.c \ | |
| @@ -0,0 +1,65 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, 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 https://curl.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. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "first.h" |
| + | |
| + | static int fnmatch2805(void *ptr, const char *pattern, const char *string) |
| + | { |
| + | (void)ptr; |
| + | curl_mprintf("match: '%s' against pattern '%s'\n", string, pattern); |
| + | return CURL_FNMATCHFUNC_MATCH; |
| + | } |
| + | |
| + | static CURLcode test_lib2805(const char *URL) |
| + | { |
| + | CURLcode result; |
| + | CURL *curl; |
| + | |
| + | if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { |
| + | curl_mfprintf(stderr, "curl_global_init() failed\n"); |
| + | return TEST_ERR_MAJOR_BAD; |
| + | } |
| + | |
| + | curl = curl_easy_init(); |
| + | if(!curl) { |
| + | curl_mfprintf(stderr, "curl_easy_init() failed\n"); |
| + | curl_global_cleanup(); |
| + | return TEST_ERR_MAJOR_BAD; |
| + | } |
| + | |
| + | easy_setopt(curl, CURLOPT_URL, URL); |
| + | easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); |
| + | easy_setopt(curl, CURLOPT_FNMATCH_FUNCTION, fnmatch2805); |
| + | easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)TEST_HANG_TIMEOUT); |
| + | |
| + | result = curl_easy_perform(curl); |
| + | if(result) { |
| + | curl_mfprintf(stderr, "curl_easy_perform() failed %d\n", (int)result); |
| + | goto test_cleanup; |
| + | } |
| + | |
| + | test_cleanup: |
| + | curl_easy_cleanup(curl); |
| + | curl_global_cleanup(); |
| + | return result; |
| + | } |