1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-15 14:05:03 -05:00

parse_filename: deal with escaped quotes

This commit is contained in:
Daniel Stenberg 2011-08-04 23:14:12 +02:00
parent a6ed2b8426
commit 8f890470f1

View File

@ -4467,21 +4467,23 @@ parse_filename(char *ptr, size_t len)
char* copy; char* copy;
char* p; char* p;
char* q; char* q;
char quote = 0; char stop = 0;
/* simple implementation of strndup() */ /* simple implementation of strndup() */
copy = malloc(len+1); copy = malloc(len+1);
if(!copy) if(!copy)
return NULL; return NULL;
strncpy(copy, ptr, len); memcpy(copy, ptr, len);
copy[len] = 0; copy[len] = 0;
p = copy; p = copy;
if(*p == '\'' || *p == '"') { if(*p == '\'' || *p == '"') {
/* store the starting quote */ /* store the starting quote */
quote = *p; stop = *p;
p++; p++;
} }
else
stop = ';';
/* if the filename contains a path, only use filename portion */ /* if the filename contains a path, only use filename portion */
q = strrchr(copy, '/'); q = strrchr(copy, '/');
@ -4505,26 +4507,25 @@ parse_filename(char *ptr, size_t len)
} }
} }
if(quote) { /* scan for the end letter and stop there */
/* if the file name started with a quote, then scan for the end quote and q = p;
stop there */ while(*q) {
q = strrchr(p, quote); if(q[1] && q[0]=='\\')
if(q) q++;
*q = 0; else if(q[0] == stop)
break;
q++;
} }
else *q = 0;
q = NULL; /* no start quote, so no end has been found */
if(!q) { /* make sure the file name doesn't end in \r or \n */
/* make sure the file name doesn't end in \r or \n */ q = strchr(p, '\r');
q = strchr(p, '\r'); if(q)
if(q) *q = 0;
*q = 0;
q = strchr(p, '\n'); q = strchr(p, '\n');
if(q) if(q)
*q = 0; *q = 0;
}
if(copy!=p) if(copy!=p)
memmove(copy, p, strlen(p)+1); memmove(copy, p, strlen(p)+1);
@ -4559,7 +4560,6 @@ header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
const char* str = (char*)ptr; const char* str = (char*)ptr;
const size_t cb = size*nmemb; const size_t cb = size*nmemb;
const char* end = (char*)ptr + cb; const char* end = (char*)ptr + cb;
size_t len;
if(cb > 20 && checkprefix("Content-disposition:", str)) { if(cb > 20 && checkprefix("Content-disposition:", str)) {
char *p = (char*)str + 20; char *p = (char*)str + 20;
@ -4568,8 +4568,7 @@ header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
(encoded filenames (*=) are not supported) */ (encoded filenames (*=) are not supported) */
for(;;) { for(;;) {
char *filename; char *filename;
char *eol; /* end of line, we can't easily search for the end of the size_t len;
file name due to it sometimes being quoted or not */
while(*p && (p < end) && !ISALPHA(*p)) while(*p && (p < end) && !ISALPHA(*p))
p++; p++;
@ -4583,12 +4582,11 @@ header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
continue; continue;
} }
p+=9; p+=9;
eol = strchr(p, '\n');
/* this expression below typecasts 'cb' only to avoid /* this expression below typecasts 'cb' only to avoid
warning: signed and unsigned type in conditional expression warning: signed and unsigned type in conditional expression
*/ */
len = eol ? (eol - p) : (ssize_t)cb - (p - str); len = (ssize_t)cb - (p - str);
filename = parse_filename(p, len); filename = parse_filename(p, len);
if(filename) { if(filename) {
outs->filename = filename; outs->filename = filename;