diff options
Diffstat (limited to 'libs/libcurl/src/curl_path.c')
-rw-r--r-- | libs/libcurl/src/curl_path.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c index 7adc040a22..f2b23fecc2 100644 --- a/libs/libcurl/src/curl_path.c +++ b/libs/libcurl/src/curl_path.c @@ -98,8 +98,8 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, return CURLE_OK;
}
-/* The get_pathname() function is being borrowed from OpenSSH sftp.c
- version 4.6p1. */
+/* The original get_pathname() function came from OpenSSH sftp.c version
+ 4.6p1. */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -115,38 +115,37 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, * 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, char *homedir)
+
+#define MAX_PATHLENGTH 65535 /* arbitrary long */
+
+CURLcode Curl_get_pathname(const char **cpp, char **path, const char *homedir)
{
const char *cp = *cpp, *end;
char quot;
- unsigned int i, j;
- size_t fullPathLength, pathLength;
- bool relativePath = false;
+ unsigned int i;
static const char WHITESPACE[] = " \t\r\n";
+ struct dynbuf out;
+ CURLcode result;
DEBUGASSERT(homedir);
- if(!*cp || !homedir) {
- *cpp = NULL;
- *path = NULL;
+ *path = NULL;
+ *cpp = NULL;
+ if(!*cp || !homedir)
return CURLE_QUOTE_ERROR;
- }
+
+ Curl_dyn_init(&out, MAX_PATHLENGTH);
+
/* 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)
- return CURLE_OUT_OF_MEMORY;
/* Check for quoted filenames */
if(*cp == '\"' || *cp == '\'') {
quot = *cp++;
/* Search for terminating quote, unescape some chars */
- for(i = j = 0; i <= strlen(cp); i++) {
+ for(i = 0; i <= strlen(cp); i++) {
if(cp[i] == quot) { /* Found quote */
i++;
- (*path)[j] = '\0';
break;
}
if(cp[i] == '\0') { /* End of string */
@@ -159,40 +158,45 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) goto fail;
}
}
- (*path)[j++] = cp[i];
+ result = Curl_dyn_addn(&out, &cp[i], 1);
+ if(result)
+ return result;
}
- if(j == 0) {
+ if(!Curl_dyn_len(&out))
goto fail;
- }
- *cpp = cp + i + strspn(cp + i, WHITESPACE);
+
+ /* return pointer to second parameter if it exists */
+ *cpp = &cp[i] + strspn(&cp[i], WHITESPACE);
}
else {
/* Read to end of filename - either to whitespace or terminator */
end = strpbrk(cp, WHITESPACE);
if(!end)
end = strchr(cp, '\0');
+
/* return pointer to second parameter if it exists */
*cpp = end + strspn(end, WHITESPACE);
- 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';
+ if(cp[0] == '/' && cp[1] == '~' && cp[2] == '/') {
+ result = Curl_dyn_add(&out, homedir);
+ if(!result)
+ result = Curl_dyn_addn(&out, "/", 1);
+ if(result)
+ return result;
cp += 3;
}
/* Copy path name up until first "whitespace" */
- memcpy(&(*path)[pathLength], cp, (int)(end - cp));
- pathLength += (int)(end - cp);
- (*path)[pathLength] = '\0';
+ result = Curl_dyn_addn(&out, cp, (end - cp));
+ if(result)
+ return result;
}
+ *path = Curl_dyn_ptr(&out);
return CURLE_OK;
fail:
- Curl_safefree(*path);
+ Curl_dyn_free(&out);
return CURLE_QUOTE_ERROR;
}
|