]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/type.c
SIGSEGV in CUPS web ui when adding a printer
[thirdparty/cups.git] / scheduler / type.c
index 8357197f3702cb8bb007088edab63e0e336816d0..f547b835836b6a49f5a5a1f4344c29ba8b98085f 100644 (file)
@@ -1,16 +1,11 @@
 /*
- * "$Id$"
- *
  * MIME typing routines for CUPS.
  *
- * Copyright 2007-2014 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products, all rights reserved.
  *
- * 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.
  */
 
 /*
  */
 
 #include <cups/string-private.h>
-#include <cups/debug-private.h>
 #include <locale.h>
 #include "mime.h"
 
 
+/*
+ * Debug macros that used to be private API...
+ */
+
+#define DEBUG_puts(x)
+#define DEBUG_printf(...)
+
+
 /*
  * Local types...
  */
@@ -50,7 +52,7 @@ static int    mime_patmatch(const char *s, const char *pat);
  * Local globals...
  */
 
-#ifdef DEBUG
+#ifdef MIME_DEBUG
 static const char * const debug_ops[] =
                {                       /* Test names... */
                  "NOP",                /* No operation */
@@ -65,7 +67,8 @@ static const char * const debug_ops[] =
                  "INT",                /* Integer/32-bit word matches */
                  "LOCALE",             /* Current locale matches string */
                  "CONTAINS",           /* File contains a string */
-                 "ISTRING"             /* Case-insensitive string matches */
+                 "ISTRING",            /* Case-insensitive string matches */
+                 "REGEX"               /* Regular expression matches */
                };
 #endif /* DEBUG */
 
@@ -448,6 +451,7 @@ mimeAddTypeRule(mime_type_t *mt,    /* I - Type to add to */
        snprintf(value[0], sizeof(value[0]), "*.%s", name);
        length[0]  = (int)strlen(value[0]);
        op         = MIME_MAGIC_MATCH;
+       num_values = 1;
       }
 
      /*
@@ -525,14 +529,16 @@ mimeAddTypeRule(mime_type_t *mt,  /* I - Type to add to */
        case MIME_MAGIC_STRING :
        case MIME_MAGIC_ISTRING :
            temp->offset = strtol(value[0], NULL, 0);
-           if ((size_t)length[1] > sizeof(temp->value.stringv))
+           if (num_values < 2 || (size_t)length[1] > sizeof(temp->value.stringv))
              return (-1);
            temp->length = length[1];
-           memcpy(temp->value.stringv, value[1], length[1]);
+           memcpy(temp->value.stringv, value[1], (size_t)length[1]);
            break;
        case MIME_MAGIC_CHAR :
            temp->offset = strtol(value[0], NULL, 0);
-           if (length[1] == 1)
+           if (num_values < 2)
+             return (-1);
+           else if (length[1] == 1)
              temp->value.charv = (unsigned char)value[1][0];
            else
              temp->value.charv = (unsigned char)strtol(value[1], NULL, 0);
@@ -557,10 +563,10 @@ mimeAddTypeRule(mime_type_t *mt,  /* I - Type to add to */
        case MIME_MAGIC_CONTAINS :
            temp->offset = strtol(value[0], NULL, 0);
            temp->region = strtol(value[1], NULL, 0);
-           if ((size_t)length[2] > sizeof(temp->value.stringv))
+           if (num_values < 3 || (size_t)length[2] > sizeof(temp->value.stringv))
              return (-1);
            temp->length = length[2];
-           memcpy(temp->value.stringv, value[2], length[2]);
+           memcpy(temp->value.stringv, value[2], (size_t)length[2]);
            break;
       }
     }
@@ -613,8 +619,23 @@ mimeFileType(mime_t     *mime,             /* I - MIME database */
     return (NULL);
   }
 
-  fb.offset = -1;
-  fb.length = 0;
+ /*
+  * Then preload the first MIME_MAX_BUFFER bytes of the file into the file
+  * buffer, returning an error if we can't read anything...
+  */
+
+  fb.offset = 0;
+  fb.length = (int)cupsFileRead(fb.fp, (char *)fb.buffer, MIME_MAX_BUFFER);
+
+  if (fb.length <= 0)
+  {
+    DEBUG_printf(("1mimeFileType: Unable to read from \"%s\": %s", pathname, strerror(errno)));
+    DEBUG_puts("1mimeFileType: Returning NULL.");
+
+    cupsFileClose(fb.fp);
+
+    return (NULL);
+  }
 
  /*
   * Figure out the base filename (without directory portion)...
@@ -780,6 +801,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ASCII fb->length=%d", fb->length));
          }
 
          /*
@@ -822,6 +845,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_PRINTABLE fb->length=%d", fb->length));
          }
 
          /*
@@ -870,6 +895,8 @@ mime_check_rules(
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
 
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_REGEX fb->length=%d", fb->length));
+
             DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts "
                          "with \"%c%c%c%c\".",
                          fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
@@ -886,7 +913,7 @@ mime_check_rules(
             char temp[MIME_MAX_BUFFER + 1];
                                        /* Temporary buffer */
 
-            memcpy(temp, fb->buffer, fb->length);
+            memcpy(temp, fb->buffer, (size_t)fb->length);
             temp[fb->length] = '\0';
             result = !regexec(&(rules->value.rev), temp, 0, NULL, 0);
           }
@@ -914,6 +941,8 @@ mime_check_rules(
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
 
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_STRING fb->length=%d", fb->length));
+
             DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts "
                          "with \"%c%c%c%c\".",
                          fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
@@ -948,6 +977,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ISTRING fb->length=%d", fb->length));
          }
 
          /*
@@ -976,6 +1007,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CHAR fb->length=%d", fb->length));
          }
 
         /*
@@ -1006,6 +1039,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_SHORT fb->length=%d", fb->length));
          }
 
         /*
@@ -1039,6 +1074,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_INT fb->length=%d", fb->length));
          }
 
         /*
@@ -1057,7 +1094,7 @@ mime_check_rules(
          break;
 
       case MIME_MAGIC_LOCALE :
-#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
+#if defined(_WIN32) || defined(__EMX__) || defined(__APPLE__)
           result = !strcmp(rules->value.localev, setlocale(LC_ALL, ""));
 #else
           result = !strcmp(rules->value.localev, setlocale(LC_MESSAGES, ""));
@@ -1080,6 +1117,8 @@ mime_check_rules(
            fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
                                      sizeof(fb->buffer));
            fb->offset = rules->offset;
+
+           DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CONTAINS fb->length=%d", fb->length));
          }
 
          /*
@@ -1243,8 +1282,3 @@ mime_patmatch(const char *s,              /* I - String to match against */
 
   return (*s == *pat);
 }
-
-
-/*
- * End of "$Id$".
- */