Commit d69a6309 authored by Dan Fandrich's avatar Dan Fandrich
Browse files

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.
parent 987b67bd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ Daniel Fandrich (30 Jul 2008)
  during redirects.  Test cases 1052 and 1055 show problems (maybe the same
  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)
- Fixed --use-ascii to properly convert text files on Symbian OS, MS-DOS
  and OS/2.
+77 −55
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@
#ifdef MSDOS
#include <dos.h>

const char *msdosify(const char *);
char *rename_if_dos_device_name(char *);
static const char *msdosify(const char *);
static char *rename_if_dos_device_name(char *);

#ifdef DJGPP
/* 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 void GetStr(char **string,
                   char *value)
                   const char *value)
{
  if(*string)
    free(*string);
@@ -962,7 +962,7 @@ static void list_engines (const struct curl_slist *engines)
 *
 * 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
 * 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 ';'

static int formparse(struct Configurable *config,
                     char *input,
                     const char *input,
                     struct curl_httppost **httppost,
                     struct curl_httppost **last_post,
                     bool literal_value)
@@ -1367,7 +1367,7 @@ static void cleanarg(char *str)
 * data.
 */

static int str2num(long *val, char *str)
static int str2num(long *val, const char *str)
{
  int retcode = 0;
  if(str && ISDIGIT(*str))
@@ -1385,7 +1385,7 @@ static int str2num(long *val, char *str)
 * @param str  the buffer containing the offset
 * @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
  /* 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,
                               char *ptr)
                               const char *ptr)
{
  struct curl_slist *newlist = curl_slist_append(*list, ptr);
  if(newlist)
@@ -1468,7 +1468,7 @@ static ParameterError add2list(struct curl_slist **list,
  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))
    return CURLFTPMETHOD_SINGLECWD;
@@ -1480,7 +1480,7 @@ static int ftpfilemethod(struct Configurable *config, char *str)
  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))
    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
           * the content.
           */
          char *p = strchr(nextarg, '=');
          const char *p = strchr(nextarg, '=');
          size_t size = 0;
          size_t nlen;
          char is_file;
@@ -2899,6 +2899,47 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
  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 */
static int parseconfig(const char *filename,
                       struct Configurable *config)
@@ -2908,6 +2949,7 @@ static int parseconfig(const char *filename,
  char filebuffer[512];
  bool usedarg;
  char *home;
  int rc = 0;

  if(!filename || !*filename) {
    /* NULL or no file name attempts to load .curlrc from the homedir! */
@@ -2991,7 +3033,7 @@ static int parseconfig(const char *filename,
      line = aline;
      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))
        line++;

@@ -3025,43 +3067,17 @@ static int parseconfig(const char *filename,

      /* the parameter starts here (unless quoted) */
      if(*line == '\"') {
        char *ptr;
        /* quoted parameter, do the qoute dance */
        /* quoted parameter, do the quote dance */
        line++;
        param=strdup(line); /* parameter */
        alloced_param=TRUE;

        ptr=param;
        while(*line && (*line != '\"')) {
          if(*line == '\\') {
            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';
        param=malloc(strlen(line)+1); /* parameter */
        if (!param) {
          /* out of memory */
          free(aline);
          rc = 1;
          break;
        }
            *ptr++=out;
            line++;
          }
          else
            *ptr++=*line++;
        }
        *ptr=0; /* always zero terminate */

        alloced_param=TRUE;
        line = (char*) unslashquote(line, param);
      }
      else {
        param=line; /* parameter starts here */
@@ -3111,8 +3127,8 @@ static int parseconfig(const char *filename,
      fclose(file);
  }
  else
    return 1; /* couldn't open the file */
  return 0;
    rc = 1; /* couldn't open the file */
  return rc;
}

static void go_sleep(long ms)
@@ -3361,8 +3377,8 @@ void progressbarinit(struct ProgressData *bar,


static
void dump(char *timebuf, const char *text,
          FILE *stream, unsigned char *ptr, size_t size,
void dump(const char *timebuf, const char *text,
          FILE *stream, const unsigned char *ptr, size_t size,
          trace tracetype, curl_infotype infotype)
{
  size_t i;
@@ -5079,6 +5095,11 @@ int main(int argc, char *argv[])
#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)
{
   char buf[4096];
@@ -5227,10 +5248,10 @@ static char *basename(char *path)
/* The following functions are taken with modification from the DJGPP
 * port of tar 1.12. They use algorithms originally from DJTAR. */

const char *
static const char *
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_w95 = &illegal_chars_dos[8];
  int idx, dot_idx;
@@ -5317,7 +5338,7 @@ msdosify (const char *file_name)
  return dos_name;
}

char *
static char *
rename_if_dos_device_name (char *file_name)
{
  /* 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;
  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);
  if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
    size_t blen = strlen (base);