]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cgi-bin/var.c
SIGSEGV in CUPS web ui when adding a printer
[thirdparty/cups.git] / cgi-bin / var.c
index 3935508fc2b92fc29c4191fe94964caa948b296c..fb9d051c0ba7e1e83fb4998e16b659ed478ea727 100644 (file)
@@ -1,16 +1,11 @@
 /*
- * "$Id$"
- *
  * CGI form variable and array functions for CUPS.
  *
- * Copyright 2007-2015 by Apple Inc.
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2005 by Easy Software Products.
  *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file.  If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
@@ -20,7 +15,6 @@
 /*#define DEBUG*/
 #include "cgi-private.h"
 #include <cups/http.h>
-#include <cups/md5-private.h>
 
 
 /*
 
 typedef struct                         /**** Form variable structure ****/
 {
-  const char   *name;                  /* Name of variable */
+  char         *name;                  /* Name of variable */
   int          nvalues,                /* Number of values */
                avalues;                /* Number of values allocated */
-  const char   **values;               /* Value(s) of variable */
+  char         **values;               /* Value(s) of variable */
 } _cgi_var_t;
 
 
@@ -120,7 +114,12 @@ cgiCheckVariables(const char *names)       /* I - Variables to look for */
       return (0);
 
     if (*val == '\0')
+    {
+      free((void *)val);
       return (0);      /* Can't be blank, either! */
+    }
+
+    free((void *)val);
   }
 
   return (1);
@@ -142,10 +141,10 @@ cgiClearVariables(void)
 
   for (v = form_vars, i = form_count; i > 0; v ++, i --)
   {
-    _cupsStrFree(v->name);
+    free(v->name);
     for (j = 0; j < v->nvalues; j ++)
       if (v->values[j])
-        _cupsStrFree(v->values[j]);
+        free(v->values[j]);
   }
 
   form_count = 0;
@@ -158,7 +157,7 @@ cgiClearVariables(void)
  * 'cgiGetArray()' - Get an element from a form array.
  */
 
-const char *                           /* O - Element value or NULL */
+char *                                 /* O - Element value or NULL */
 cgiGetArray(const char *name,          /* I - Name of array variable */
             int        element)                /* I - Element number (0 to N) */
 {
@@ -171,7 +170,10 @@ cgiGetArray(const char *name,              /* I - Name of array variable */
   if (element < 0 || element >= var->nvalues)
     return (NULL);
 
-  return (_cupsStrRetain(var->values[element]));
+  if (var->values[element] == NULL)
+    return (NULL);
+
+  return (strdup(var->values[element]));
 }
 
 
@@ -221,7 +223,7 @@ cgiGetSize(const char *name)                /* I - Name of variable */
  * array of values, returns the last element.
  */
 
-const char *                           /* O - Value of variable */
+char *                                 /* O - Value of variable */
 cgiGetVariable(const char *name)       /* I - Name of variable */
 {
   const _cgi_var_t     *var;           /* Returned variable */
@@ -229,15 +231,7 @@ cgiGetVariable(const char *name)   /* I - Name of variable */
 
   var = cgi_find_variable(name);
 
-#ifdef DEBUG
-  if (var == NULL)
-    DEBUG_printf(("cgiGetVariable(\"%s\") is returning NULL...\n", name));
-  else
-    DEBUG_printf(("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name,
-                 var->values[var->nvalues - 1]));
-#endif /* DEBUG */
-
-  return ((var == NULL) ? NULL : _cupsStrRetain(var->values[var->nvalues - 1]));
+  return ((var == NULL) ? NULL : strdup(var->values[var->nvalues - 1]));
 }
 
 
@@ -327,11 +321,18 @@ cgiInitialize(void)
       else
        fputs("DEBUG: " CUPS_SID " form variable is not present.\n", stderr);
 
+      free((void *)cups_sid_form);
+
       cgiClearVariables();
+
       return (0);
     }
     else
+    {
+      free((void *)cups_sid_form);
+
       return (1);
+    }
   }
   else
     return (0);
@@ -385,10 +386,9 @@ cgiSetArray(const char *name,              /* I - Name of variable */
   {
     if (element >= var->avalues)
     {
-      const char **temp;               /* Temporary pointer */
+      char **temp;                     /* Temporary pointer */
 
-      temp = (const char **)realloc((void *)(var->values),
-                                    sizeof(char *) * (size_t)(element + 16));
+      temp = (char **)realloc((void *)(var->values), sizeof(char *) * (size_t)(element + 16));
       if (!temp)
         return;
 
@@ -404,9 +404,9 @@ cgiSetArray(const char *name,               /* I - Name of variable */
       var->nvalues = element + 1;
     }
     else if (var->values[element])
-      _cupsStrFree((char *)var->values[element]);
+      free((char *)var->values[element]);
 
-    var->values[element] = _cupsStrAlloc(value);
+    var->values[element] = strdup(value);
   }
 }
 
@@ -463,10 +463,9 @@ cgiSetSize(const char *name,               /* I - Name of variable */
 
   if (size >= var->avalues)
   {
-    const char **temp;                 /* Temporary pointer */
+    char **temp;                       /* Temporary pointer */
 
-    temp = (const char **)realloc((void *)(var->values),
-                                 sizeof(char *) * (size_t)(size + 16));
+    temp = (char **)realloc((void *)(var->values), sizeof(char *) * (size_t)(size + 16));
     if (!temp)
       return;
 
@@ -483,7 +482,7 @@ cgiSetSize(const char *name,                /* I - Name of variable */
   {
     for (i = size; i < var->nvalues; i ++)
       if (var->values[i])
-        _cupsStrFree((void *)(var->values[i]));
+        free((void *)(var->values[i]));
   }
 
   var->nvalues = size;
@@ -518,9 +517,9 @@ cgiSetVariable(const char *name,    /* I - Name of variable */
   {
     for (i = 0; i < var->nvalues; i ++)
       if (var->values[i])
-        _cupsStrFree((char *)var->values[i]);
+        free((char *)var->values[i]);
 
-    var->values[0] = _cupsStrAlloc(value);
+    var->values[0] = strdup(value);
     var->nvalues   = 1;
   }
 }
@@ -541,9 +540,6 @@ cgi_add_variable(const char *name,  /* I - Variable name */
   if (name == NULL || value == NULL || element < 0 || element > 100000)
     return;
 
-  DEBUG_printf(("cgi_add_variable: Adding variable \'%s\' with value "
-                "\'%s\'...\n", name, value));
-
   if (form_count >= form_alloc)
   {
     _cgi_var_t *temp_vars;             /* Temporary form pointer */
@@ -566,10 +562,10 @@ cgi_add_variable(const char *name,        /* I - Variable name */
   if ((var->values = calloc((size_t)element + 1, sizeof(char *))) == NULL)
     return;
 
-  var->name            = _cupsStrAlloc(name);
+  var->name            = strdup(name);
   var->nvalues         = element + 1;
   var->avalues         = element + 1;
-  var->values[element] = _cupsStrAlloc(value);
+  var->values[element] = strdup(value);
 
   form_count ++;
 }
@@ -601,7 +597,7 @@ cgi_find_variable(const char *name) /* I - Name of variable */
   if (form_count < 1 || name == NULL)
     return (NULL);
 
-  key.name = name;
+  key.name = (char *)name;
 
   return ((_cgi_var_t *)bsearch(&key, form_vars, (size_t)form_count, sizeof(_cgi_var_t),
                            (int (*)(const void *, const void *))cgi_compare_variables));
@@ -722,8 +718,6 @@ cgi_initialize_get(void)
   char *data;                          /* Pointer to form data string */
 
 
-  DEBUG_puts("cgi_initialize_get: Initializing variables using GET method...");
-
  /*
   * Check to see if there is anything for us to read...
   */
@@ -763,8 +757,6 @@ cgi_initialize_multipart(
   size_t       blen;                   /* Length of boundary string */
 
 
-  DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary));
-
  /*
   * Read multipart form data until we run out...
   */
@@ -892,12 +884,13 @@ cgi_initialize_multipart(
          if (line[0])
             cgiSetArray(name, atoi(ptr) - 1, line);
        }
-       else if (cgiGetVariable(name))
+       else if ((ptr = cgiGetVariable(name)) != NULL)
        {
         /*
          * Add another element in the array...
          */
 
+          free(ptr);
          cgiSetArray(name, cgiGetSize(name), line);
        }
        else
@@ -977,8 +970,6 @@ cgi_initialize_post(void)
   int          status;                 /* Return status */
 
 
-  DEBUG_puts("cgi_initialize_post: Initializing variables using POST method...");
-
  /*
   * Check to see if there is anything for us to read...
   */
@@ -1054,7 +1045,8 @@ cgi_initialize_string(const char *data)   /* I - Form data string */
   char *s,                             /* Pointer to current form string */
        ch,                             /* Temporary character */
        name[255],                      /* Name of form variable */
-       value[65536];                   /* Variable value */
+       value[65536],                   /* Variable value */
+       *temp;                          /* Temporary pointer */
 
 
  /*
@@ -1156,8 +1148,11 @@ cgi_initialize_string(const char *data)  /* I - Form data string */
       if (value[0])
         cgiSetArray(name, atoi(s) - 1, value);
     }
-    else if (cgiGetVariable(name) != NULL)
+    else if ((temp = cgiGetVariable(name)) != NULL)
+    {
+      free(temp);
       cgiSetArray(name, cgiGetSize(name), value);
+    }
     else
       cgiSetVariable(name, value);
   }
@@ -1206,11 +1201,11 @@ cgi_set_sid(void)
 {
   char                 buffer[512],    /* SID data */
                        sid[33];        /* SID string */
-  _cups_md5_state_t    md5;            /* MD5 state */
   unsigned char                sum[16];        /* MD5 sum */
   const char           *remote_addr,   /* REMOTE_ADDR */
                        *server_name,   /* SERVER_NAME */
                        *server_port;   /* SERVER_PORT */
+  struct timeval       curtime;        /* Current time */
 
 
   if ((remote_addr = getenv("REMOTE_ADDR")) == NULL)
@@ -1220,18 +1215,17 @@ cgi_set_sid(void)
   if ((server_port = getenv("SERVER_PORT")) == NULL)
     server_port = "SERVER_PORT";
 
-  CUPS_SRAND(time(NULL));
+  gettimeofday(&curtime, NULL);
+  CUPS_SRAND(curtime.tv_sec + curtime.tv_usec);
   snprintf(buffer, sizeof(buffer), "%s:%s:%s:%02X%02X%02X%02X%02X%02X%02X%02X",
            remote_addr, server_name, server_port,
           (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255,
           (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255,
           (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255,
           (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255);
-  _cupsMD5Init(&md5);
-  _cupsMD5Append(&md5, (unsigned char *)buffer, (int)strlen(buffer));
-  _cupsMD5Finish(&md5, sum);
+  cupsHashData("md5", (unsigned char *)buffer, strlen(buffer), sum, sizeof(sum));
 
-  cgiSetCookie(CUPS_SID, httpMD5String(sum, sid), "/", NULL, 0, 0);
+  cgiSetCookie(CUPS_SID, cupsHashString(sum, sizeof(sum), sid, sizeof(sid)), "/", NULL, 0, 0);
 
   return (cupsGetOption(CUPS_SID, num_cookies, cookies));
 }
@@ -1244,26 +1238,11 @@ cgi_set_sid(void)
 static void
 cgi_sort_variables(void)
 {
-#ifdef DEBUG
-  int  i;
-
-
-  DEBUG_puts("cgi_sort_variables: Sorting variables...");
-#endif /* DEBUG */
-
   if (form_count < 2)
     return;
 
   qsort(form_vars, (size_t)form_count, sizeof(_cgi_var_t),
         (int (*)(const void *, const void *))cgi_compare_variables);
-
-#ifdef DEBUG
-  DEBUG_puts("cgi_sort_variables: Sorted variable list is:");
-  for (i = 0; i < form_count; i ++)
-    DEBUG_printf(("cgi_sort_variables: %d: %s (%d) = \"%s\" ...\n", i,
-                  form_vars[i].name, form_vars[i].nvalues,
-                 form_vars[i].values[0]));
-#endif /* DEBUG */
 }
 
 
@@ -1294,8 +1273,3 @@ cgi_unlink_file(void)
     form_file = NULL;
   }
 }
-
-
-/*
- * End of "$Id$".
- */