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;
  }
  | 
