Fixed a couple of buffer overflows in the MS-DOS port of the curl tool.
Factored out unslashquote. Added some 'const's in function parameters.
This commit is contained in:
parent
987b67bd2e
commit
d69a630989
2
CHANGES
2
CHANGES
@ -27,6 +27,8 @@ Daniel Fandrich (30 Jul 2008)
|
|||||||
during redirects. Test cases 1052 and 1055 show problems (maybe the same
|
during redirects. Test cases 1052 and 1055 show problems (maybe the same
|
||||||
root cause as 1051) and are disabled.
|
root cause as 1051) and are disabled.
|
||||||
|
|
||||||
|
- Fixed a couple of buffer overflows in the MS-DOS port of the curl tool.
|
||||||
|
|
||||||
Daniel Fandrich (29 Jul 2008)
|
Daniel Fandrich (29 Jul 2008)
|
||||||
- Fixed --use-ascii to properly convert text files on Symbian OS, MS-DOS
|
- Fixed --use-ascii to properly convert text files on Symbian OS, MS-DOS
|
||||||
and OS/2.
|
and OS/2.
|
||||||
|
132
src/main.c
132
src/main.c
@ -154,8 +154,8 @@
|
|||||||
#ifdef MSDOS
|
#ifdef MSDOS
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
|
||||||
const char *msdosify(const char *);
|
static const char *msdosify(const char *);
|
||||||
char *rename_if_dos_device_name(char *);
|
static char *rename_if_dos_device_name(char *);
|
||||||
|
|
||||||
#ifdef DJGPP
|
#ifdef DJGPP
|
||||||
/* we want to glob our own argv[] */
|
/* we want to glob our own argv[] */
|
||||||
@ -811,7 +811,7 @@ static char *my_get_line(FILE *fp);
|
|||||||
static int create_dir_hierarchy(const char *outfile, FILE *errors);
|
static int create_dir_hierarchy(const char *outfile, FILE *errors);
|
||||||
|
|
||||||
static void GetStr(char **string,
|
static void GetStr(char **string,
|
||||||
char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
if(*string)
|
if(*string)
|
||||||
free(*string);
|
free(*string);
|
||||||
@ -962,7 +962,7 @@ static void list_engines (const struct curl_slist *engines)
|
|||||||
*
|
*
|
||||||
* formparse()
|
* formparse()
|
||||||
*
|
*
|
||||||
* Reads a 'name=value' paramter and builds the appropriate linked list.
|
* Reads a 'name=value' parameter and builds the appropriate linked list.
|
||||||
*
|
*
|
||||||
* Specify files to upload with 'name=@filename'. Supports specified
|
* Specify files to upload with 'name=@filename'. Supports specified
|
||||||
* given Content-Type of the files. Such as ';type=<content-type>'.
|
* given Content-Type of the files. Such as ';type=<content-type>'.
|
||||||
@ -999,7 +999,7 @@ static void list_engines (const struct curl_slist *engines)
|
|||||||
#define FORM_TYPE_SEPARATOR ';'
|
#define FORM_TYPE_SEPARATOR ';'
|
||||||
|
|
||||||
static int formparse(struct Configurable *config,
|
static int formparse(struct Configurable *config,
|
||||||
char *input,
|
const char *input,
|
||||||
struct curl_httppost **httppost,
|
struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
struct curl_httppost **last_post,
|
||||||
bool literal_value)
|
bool literal_value)
|
||||||
@ -1367,7 +1367,7 @@ static void cleanarg(char *str)
|
|||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int str2num(long *val, char *str)
|
static int str2num(long *val, const char *str)
|
||||||
{
|
{
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
if(str && ISDIGIT(*str))
|
if(str && ISDIGIT(*str))
|
||||||
@ -1385,7 +1385,7 @@ static int str2num(long *val, char *str)
|
|||||||
* @param str the buffer containing the offset
|
* @param str the buffer containing the offset
|
||||||
* @return zero if successful, non-zero if failure.
|
* @return zero if successful, non-zero if failure.
|
||||||
*/
|
*/
|
||||||
static int str2offset(curl_off_t *val, char *str)
|
static int str2offset(curl_off_t *val, const char *str)
|
||||||
{
|
{
|
||||||
#if SIZEOF_CURL_OFF_T > 4
|
#if SIZEOF_CURL_OFF_T > 4
|
||||||
/* Ugly, but without going through a bunch of rigmarole, we don't have the
|
/* Ugly, but without going through a bunch of rigmarole, we don't have the
|
||||||
@ -1457,7 +1457,7 @@ static void checkpasswd(const char *kind, /* for what purpose */
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ParameterError add2list(struct curl_slist **list,
|
static ParameterError add2list(struct curl_slist **list,
|
||||||
char *ptr)
|
const char *ptr)
|
||||||
{
|
{
|
||||||
struct curl_slist *newlist = curl_slist_append(*list, ptr);
|
struct curl_slist *newlist = curl_slist_append(*list, ptr);
|
||||||
if(newlist)
|
if(newlist)
|
||||||
@ -1468,7 +1468,7 @@ static ParameterError add2list(struct curl_slist **list,
|
|||||||
return PARAM_OK;
|
return PARAM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftpfilemethod(struct Configurable *config, char *str)
|
static int ftpfilemethod(struct Configurable *config, const char *str)
|
||||||
{
|
{
|
||||||
if(curlx_strequal("singlecwd", str))
|
if(curlx_strequal("singlecwd", str))
|
||||||
return CURLFTPMETHOD_SINGLECWD;
|
return CURLFTPMETHOD_SINGLECWD;
|
||||||
@ -1480,7 +1480,7 @@ static int ftpfilemethod(struct Configurable *config, char *str)
|
|||||||
return CURLFTPMETHOD_MULTICWD;
|
return CURLFTPMETHOD_MULTICWD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftpcccmethod(struct Configurable *config, char *str)
|
static int ftpcccmethod(struct Configurable *config, const char *str)
|
||||||
{
|
{
|
||||||
if(curlx_strequal("passive", str))
|
if(curlx_strequal("passive", str))
|
||||||
return CURLFTPSSL_CCC_PASSIVE;
|
return CURLFTPSSL_CCC_PASSIVE;
|
||||||
@ -2230,7 +2230,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
* Case 2: we first load the file using that name and then encode
|
* Case 2: we first load the file using that name and then encode
|
||||||
* the content.
|
* the content.
|
||||||
*/
|
*/
|
||||||
char *p = strchr(nextarg, '=');
|
const char *p = strchr(nextarg, '=');
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
char is_file;
|
char is_file;
|
||||||
@ -2899,6 +2899,47 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
return PARAM_OK;
|
return PARAM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copies the string from line to the buffer at param, unquoting
|
||||||
|
* backslash-quoted characters and NUL-terminating the output string.
|
||||||
|
* Stops at the first non-backslash-quoted double quote character or the
|
||||||
|
* end of the input string. param must be at least as long as the input
|
||||||
|
* string. Returns the pointer after the last handled input character.
|
||||||
|
*/
|
||||||
|
static const char *unslashquote(const char *line, char *param)
|
||||||
|
{
|
||||||
|
while(*line && (*line != '\"')) {
|
||||||
|
if(*line == '\\') {
|
||||||
|
char out;
|
||||||
|
line++;
|
||||||
|
|
||||||
|
/* default is to output the letter after the backslash */
|
||||||
|
switch(out = *line) {
|
||||||
|
case '\0':
|
||||||
|
continue; /* this'll break out of the loop */
|
||||||
|
case 't':
|
||||||
|
out='\t';
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
out='\n';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
out='\r';
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
out='\v';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*param++=out;
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*param++=*line++;
|
||||||
|
}
|
||||||
|
*param=0; /* always zero terminate */
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
/* return 0 on everything-is-fine, and non-zero otherwise */
|
/* return 0 on everything-is-fine, and non-zero otherwise */
|
||||||
static int parseconfig(const char *filename,
|
static int parseconfig(const char *filename,
|
||||||
struct Configurable *config)
|
struct Configurable *config)
|
||||||
@ -2908,6 +2949,7 @@ static int parseconfig(const char *filename,
|
|||||||
char filebuffer[512];
|
char filebuffer[512];
|
||||||
bool usedarg;
|
bool usedarg;
|
||||||
char *home;
|
char *home;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if(!filename || !*filename) {
|
if(!filename || !*filename) {
|
||||||
/* NULL or no file name attempts to load .curlrc from the homedir! */
|
/* NULL or no file name attempts to load .curlrc from the homedir! */
|
||||||
@ -2991,7 +3033,7 @@ static int parseconfig(const char *filename,
|
|||||||
line = aline;
|
line = aline;
|
||||||
alloced_param=FALSE;
|
alloced_param=FALSE;
|
||||||
|
|
||||||
/* lines with # in the fist column is a comment! */
|
/* line with # in the first non-blank column is a comment! */
|
||||||
while(*line && ISSPACE(*line))
|
while(*line && ISSPACE(*line))
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
@ -3025,43 +3067,17 @@ static int parseconfig(const char *filename,
|
|||||||
|
|
||||||
/* the parameter starts here (unless quoted) */
|
/* the parameter starts here (unless quoted) */
|
||||||
if(*line == '\"') {
|
if(*line == '\"') {
|
||||||
char *ptr;
|
/* quoted parameter, do the quote dance */
|
||||||
/* quoted parameter, do the qoute dance */
|
|
||||||
line++;
|
line++;
|
||||||
param=strdup(line); /* parameter */
|
param=malloc(strlen(line)+1); /* parameter */
|
||||||
alloced_param=TRUE;
|
if (!param) {
|
||||||
|
/* out of memory */
|
||||||
ptr=param;
|
free(aline);
|
||||||
while(*line && (*line != '\"')) {
|
rc = 1;
|
||||||
if(*line == '\\') {
|
break;
|
||||||
char out;
|
|
||||||
line++;
|
|
||||||
|
|
||||||
/* default is to output the letter after the backslah */
|
|
||||||
switch(out = *line) {
|
|
||||||
case '\0':
|
|
||||||
continue; /* this'll break out of the loop */
|
|
||||||
case 't':
|
|
||||||
out='\t';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
out='\n';
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
out='\r';
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
out='\v';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*ptr++=out;
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*ptr++=*line++;
|
|
||||||
}
|
}
|
||||||
*ptr=0; /* always zero terminate */
|
alloced_param=TRUE;
|
||||||
|
line = (char*) unslashquote(line, param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
param=line; /* parameter starts here */
|
param=line; /* parameter starts here */
|
||||||
@ -3111,8 +3127,8 @@ static int parseconfig(const char *filename,
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 1; /* couldn't open the file */
|
rc = 1; /* couldn't open the file */
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void go_sleep(long ms)
|
static void go_sleep(long ms)
|
||||||
@ -3361,8 +3377,8 @@ void progressbarinit(struct ProgressData *bar,
|
|||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void dump(char *timebuf, const char *text,
|
void dump(const char *timebuf, const char *text,
|
||||||
FILE *stream, unsigned char *ptr, size_t size,
|
FILE *stream, const unsigned char *ptr, size_t size,
|
||||||
trace tracetype, curl_infotype infotype)
|
trace tracetype, curl_infotype infotype)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -5079,6 +5095,11 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reads a line from the given file, ensuring is NUL terminated.
|
||||||
|
* The pointer must be freed by the caller.
|
||||||
|
* NULL is returned on an out of memory condition.
|
||||||
|
*/
|
||||||
static char *my_get_line(FILE *fp)
|
static char *my_get_line(FILE *fp)
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
@ -5227,10 +5248,10 @@ static char *basename(char *path)
|
|||||||
/* The following functions are taken with modification from the DJGPP
|
/* The following functions are taken with modification from the DJGPP
|
||||||
* port of tar 1.12. They use algorithms originally from DJTAR. */
|
* port of tar 1.12. They use algorithms originally from DJTAR. */
|
||||||
|
|
||||||
const char *
|
static const char *
|
||||||
msdosify (const char *file_name)
|
msdosify (const char *file_name)
|
||||||
{
|
{
|
||||||
static char dos_name[PATH_MAX];
|
static char dos_name[PATH_MAX*2];
|
||||||
static const char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
|
static const char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
|
||||||
static const char *illegal_chars_w95 = &illegal_chars_dos[8];
|
static const char *illegal_chars_w95 = &illegal_chars_dos[8];
|
||||||
int idx, dot_idx;
|
int idx, dot_idx;
|
||||||
@ -5317,7 +5338,7 @@ msdosify (const char *file_name)
|
|||||||
return dos_name;
|
return dos_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
rename_if_dos_device_name (char *file_name)
|
rename_if_dos_device_name (char *file_name)
|
||||||
{
|
{
|
||||||
/* We could have a file whose name is a device on MS-DOS. Trying to
|
/* We could have a file whose name is a device on MS-DOS. Trying to
|
||||||
@ -5327,7 +5348,8 @@ rename_if_dos_device_name (char *file_name)
|
|||||||
struct stat st_buf;
|
struct stat st_buf;
|
||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
|
|
||||||
strcpy (fname, file_name);
|
strncpy(fname, file_name, PATH_MAX-1);
|
||||||
|
fname[PATH_MAX-2] = 0; /* Leave room for an extra _ */
|
||||||
base = basename (fname);
|
base = basename (fname);
|
||||||
if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
|
if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
|
||||||
size_t blen = strlen (base);
|
size_t blen = strlen (base);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user