From d29e14c868c96f4011dbd380dfb18fda33755c5d Mon Sep 17 00:00:00 2001 From: John DeHelian Date: Fri, 8 Dec 2017 11:31:01 -0500 Subject: [PATCH] Allow quoted commands to use relative paths #1900 Rebased (Cherry picked changes) into master @912324024b3be13ef9c3eedfc437a9fcb7961228 --- lib/curl_path.c | 34 +++++++++++++++++++++++++--------- lib/curl_path.h | 3 +-- lib/ssh-libssh.c | 8 ++++---- lib/ssh.c | 8 ++++---- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/curl_path.c b/lib/curl_path.c index cd659209639d44..e843deac7cfe06 100644 --- a/lib/curl_path.c +++ b/lib/curl_path.c @@ -110,21 +110,25 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -CURLcode Curl_get_pathname(const char **cpp, char **path) +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) { const char *cp = *cpp, *end; char quot; unsigned int i, j; + size_t fullPathLength, pathLength; + bool relativePath = false; static const char WHITESPACE[] = " \t\r\n"; - cp += strspn(cp, WHITESPACE); if(!*cp) { - *cpp = cp; + *cpp = NULL; *path = NULL; return CURLE_QUOTE_ERROR; } - - *path = malloc(strlen(cp) + 1); + /* Ignore leading whitespace */ + cp += strspn(cp, WHITESPACE); + /* Allocate enough space for home directory and filename + separator */ + fullPathLength = strlen(cp) + strlen(homedir) + 2; + *path = malloc(fullPathLength); if(*path == NULL) return CURLE_OUT_OF_MEMORY; @@ -162,14 +166,26 @@ CURLcode Curl_get_pathname(const char **cpp, char **path) *cpp = cp + i + strspn(cp + i, WHITESPACE); } else { - /* Read to end of filename */ + /* Read to end of filename - either to white space or terminator */ end = strpbrk(cp, WHITESPACE); if(end == NULL) end = strchr(cp, '\0'); + /* return pointer to second parameter if it exists */ *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; + pathLength = 0; + relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/'); + /* Handling for relative path - prepend home directory */ + if(relativePath) { + strcpy(*path, homedir); + pathLength = strlen(homedir); + (*path)[pathLength++] = '/'; + (*path)[pathLength] = '\0'; + cp += 3; + } + /* Copy path name up until first "white space" */ + memcpy(&(*path)[pathLength], cp, (int)(end - cp)); + pathLength += (int)(end - cp); + (*path)[pathLength] = '\0'; } return CURLE_OK; diff --git a/lib/curl_path.h b/lib/curl_path.h index 3ce16eb88699f2..f9d4327508ad83 100644 --- a/lib/curl_path.h +++ b/lib/curl_path.h @@ -41,5 +41,4 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, char *homedir, char **path); -CURLcode -Curl_get_pathname(const char **cpp, char **path); +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir); diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c index 822a7419c1efce..fb49a22d55e555 100644 --- a/lib/ssh-libssh.c +++ b/lib/ssh-libssh.c @@ -2534,7 +2534,7 @@ static void sftp_quote(struct connectdata *conn) * also, every command takes at least one argument so we get that * first argument right now */ - result = Curl_get_pathname(&cp, &sshc->quote_path1); + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2559,7 +2559,7 @@ static void sftp_quote(struct connectdata *conn) /* sshc->quote_path1 contains the mode to set */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2581,7 +2581,7 @@ static void sftp_quote(struct connectdata *conn) /* symbolic linking */ /* sshc->quote_path1 is the source */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2605,7 +2605,7 @@ static void sftp_quote(struct connectdata *conn) /* rename file */ /* first param is the source path */ /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); diff --git a/lib/ssh.c b/lib/ssh.c index a4dd878bfcc4d0..bf07432bdd37d2 100644 --- a/lib/ssh.c +++ b/lib/ssh.c @@ -1205,7 +1205,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * also, every command takes at least one argument so we get that * first argument right now */ - result = Curl_get_pathname(&cp, &sshc->quote_path1); + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1230,7 +1230,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* sshc->quote_path1 contains the mode to set */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1252,7 +1252,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* symbolic linking */ /* sshc->quote_path1 is the source */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1277,7 +1277,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* rename file */ /* first param is the source path */ /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory");