]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - filter/interpret.c
Fix another potential buffer overflow (STR #4599)
[thirdparty/cups.git] / filter / interpret.c
index 7d0cb570a387664cc9fe05924f9f1cc749c31639..380fa1d5587e2a76d882a1ddc8c7cf9cc5063dcc 100644 (file)
@@ -1,46 +1,25 @@
 /*
- * "$Id: interpret.c 7852 2008-08-21 04:19:45Z mike $"
+ * "$Id$"
  *
- *   PPD command interpreter for CUPS.
+ * PPD command interpreter for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
- *   Copyright 1993-2007 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1993-2007 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/".
+ * 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/".
  *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   cupsRasterInterpretPPD() - Interpret PPD commands to create a page header.
- *   _cupsRasterExecPS()      - Execute PostScript code to initialize a page
- *                              header.
- *   cleartomark_stack()      - Clear to the last mark ([) on the stack.
- *   copy_stack()             - Copy the top N stack objects.
- *   delete_stack()           - Free memory used by a stack.
- *   error_object()           - Add an object's value to the current error
- *                              message.
- *   error_stack()            - Add a stack to the current error message.
- *   index_stack()            - Copy the Nth value on the stack.
- *   new_stack()              - Create a new stack.
- *   pop_stock()              - Pop the top object off the stack.
- *   push_stack()             - Push an object on the stack.
- *   roll_stack()             - Rotate stack objects.
- *   scan_ps()                - Scan a string for the next PS object.
- *   setpagedevice()          - Simulate the PostScript setpagedevice operator.
- *   DEBUG_object()           - Print an object value.
- *   DEBUG_stack()            - Print a stack.
+ * This file is subject to the Apple OS-Developed Software exception.
  */
 
 /*
  * Include necessary headers...
  */
 
-#include "image-private.h"
+#include <cups/raster-private.h>
 
 
 /*
@@ -144,7 +123,7 @@ static void         DEBUG_stack(_cups_ps_stack_t *st);
  * @code pop@, @code roll@, @code setpagedevice@, and @code stopped@ operators
  * are supported.
  *
- * @since CUPS 1.2/Mac OS X 10.5@
+ * @since CUPS 1.2/OS X 10.5@
  */
 
 int                                    /* O - 0 on success, -1 on failure */
@@ -162,7 +141,8 @@ cupsRasterInterpretPPD(
   float                left,                   /* Left position */
                bottom,                 /* Bottom position */
                right,                  /* Right position */
-               top;                    /* Top position */
+               top,                    /* Top position */
+               temp1, temp2;           /* Temporary variables for swapping */
   int          preferred_bits;         /* Preferred bits per color */
 
 
@@ -189,7 +169,7 @@ cupsRasterInterpretPPD(
   h->PageSize[1]                 = 792;
   h->HWResolution[0]             = 100;
   h->HWResolution[1]             = 100;
-  h->cupsBitsPerColor            =  1;
+  h->cupsBitsPerColor            = 1;
   h->cupsColorOrder              = CUPS_ORDER_CHUNKED;
   h->cupsColorSpace              = CUPS_CSPACE_K;
   h->cupsBorderlessScalingFactor = 1.0f;
@@ -200,11 +180,11 @@ cupsRasterInterpretPPD(
   h->cupsImagingBBox[2]          = 612.0f;
   h->cupsImagingBBox[3]          = 792.0f;
 
-  strcpy(h->cupsPageSizeName, "Letter");
+  strlcpy(h->cupsPageSizeName, "Letter", sizeof(h->cupsPageSizeName));
 
 #ifdef __APPLE__
  /*
-  * cupsInteger0 is also used for the total page count on Mac OS X; set an
+  * cupsInteger0 is also used for the total page count on OS X; set an
   * uncommon default value so we can tell if the driver is using cupsInteger0.
   */
 
@@ -301,6 +281,67 @@ cupsRasterInterpretPPD(
     top    = 792.0f;
   }
 
+ /*
+  * Handle orientation...
+  */
+
+  switch (h->Orientation)
+  {
+    case CUPS_ORIENT_0 :
+    default :
+        /* Do nothing */
+        break;
+
+    case CUPS_ORIENT_90 :
+        temp1              = h->cupsPageSize[0];
+        h->cupsPageSize[0] = h->cupsPageSize[1];
+        h->cupsPageSize[1] = temp1;
+
+        temp1  = left;
+        temp2  = right;
+        left   = h->cupsPageSize[0] - top;
+        right  = h->cupsPageSize[0] - bottom;
+        bottom = h->cupsPageSize[1] - temp1;
+        top    = h->cupsPageSize[1] - temp2;
+        break;
+
+    case CUPS_ORIENT_180 :
+        temp1  = left;
+        temp2  = bottom;
+        left   = h->cupsPageSize[0] - right;
+        right  = h->cupsPageSize[0] - temp1;
+        bottom = h->cupsPageSize[1] - top;
+        top    = h->cupsPageSize[1] - temp2;
+        break;
+
+    case CUPS_ORIENT_270 :
+        temp1              = h->cupsPageSize[0];
+        h->cupsPageSize[0] = h->cupsPageSize[1];
+        h->cupsPageSize[1] = temp1;
+
+        temp1  = left;
+        temp2  = right;
+        left   = bottom;
+        right  = top;
+        bottom = h->cupsPageSize[1] - temp2;
+        top    = h->cupsPageSize[1] - temp1;
+        break;
+  }
+
+  if (left > right)
+  {
+    temp1 = left;
+    left  = right;
+    right = temp1;
+  }
+
+  if (bottom > top)
+  {
+    temp1  = bottom;
+    bottom = top;
+    top    = temp1;
+  }
+
   h->PageSize[0]           = (unsigned)(h->cupsPageSize[0] *
                                         h->cupsBorderlessScalingFactor);
   h->PageSize[1]           = (unsigned)(h->cupsPageSize[1] *
@@ -352,9 +393,9 @@ cupsRasterInterpretPPD(
   * Compute the bitmap parameters...
   */
 
-  h->cupsWidth  = (int)((right - left) * h->cupsBorderlessScalingFactor *
+  h->cupsWidth  = (unsigned)((right - left) * h->cupsBorderlessScalingFactor *
                         h->HWResolution[0] / 72.0f + 0.5f);
-  h->cupsHeight = (int)((top - bottom) * h->cupsBorderlessScalingFactor *
+  h->cupsHeight = (unsigned)((top - bottom) * h->cupsBorderlessScalingFactor *
                         h->HWResolution[1] / 72.0f + 0.5f);
 
   switch (h->cupsColorSpace)
@@ -364,6 +405,7 @@ cupsRasterInterpretPPD(
     case CUPS_CSPACE_WHITE :
     case CUPS_CSPACE_GOLD :
     case CUPS_CSPACE_SILVER :
+    case CUPS_CSPACE_SW :
         h->cupsNumColors    = 1;
         h->cupsBitsPerPixel = h->cupsBitsPerColor;
        break;
@@ -425,6 +467,29 @@ cupsRasterInterpretPPD(
 
         h->cupsNumColors = 4;
        break;
+
+    case CUPS_CSPACE_DEVICE1 :
+    case CUPS_CSPACE_DEVICE2 :
+    case CUPS_CSPACE_DEVICE3 :
+    case CUPS_CSPACE_DEVICE4 :
+    case CUPS_CSPACE_DEVICE5 :
+    case CUPS_CSPACE_DEVICE6 :
+    case CUPS_CSPACE_DEVICE7 :
+    case CUPS_CSPACE_DEVICE8 :
+    case CUPS_CSPACE_DEVICE9 :
+    case CUPS_CSPACE_DEVICEA :
+    case CUPS_CSPACE_DEVICEB :
+    case CUPS_CSPACE_DEVICEC :
+    case CUPS_CSPACE_DEVICED :
+    case CUPS_CSPACE_DEVICEE :
+    case CUPS_CSPACE_DEVICEF :
+        h->cupsNumColors = h->cupsColorSpace - CUPS_CSPACE_DEVICE1 + 1;
+
+        if (h->cupsColorOrder == CUPS_ORDER_CHUNKED)
+          h->cupsBitsPerPixel = h->cupsBitsPerColor * h->cupsNumColors;
+       else
+         h->cupsBitsPerPixel = h->cupsBitsPerColor;
+       break;
   }
 
   h->cupsBytesPerLine = (h->cupsBitsPerPixel * h->cupsWidth + 7) / 8;
@@ -446,6 +511,7 @@ _cupsRasterExecPS(
     int                 *preferred_bits,/* O - Preferred bits per color */
     const char          *code)         /* I - PS code to execute */
 {
+  int                  error = 0;      /* Error condition? */
   _cups_ps_stack_t     *st;            /* PostScript value stack */
   _cups_ps_obj_t       *obj;           /* Object from top of stack */
   char                 *codecopy,      /* Copy of code */
@@ -453,7 +519,7 @@ _cupsRasterExecPS(
 
 
   DEBUG_printf(("_cupsRasterExecPS(h=%p, preferred_bits=%p, code=\"%s\")\n",
-                h, preferred_bits, code ? code : "(null)"));
+                h, preferred_bits, code));
 
  /*
   * Copy the PostScript code and create a stack...
@@ -588,12 +654,13 @@ _cupsRasterExecPS(
 
       case CUPS_PS_OTHER :
           _cupsRasterAddError("Unknown operator \"%s\"!\n", obj->value.other);
+         error = 1;
           DEBUG_printf(("_cupsRasterExecPS: Unknown operator \"%s\"!\n",
                        obj->value.other));
           break;
     }
 
-    if (obj && obj->type == CUPS_PS_OTHER)
+    if (error)
       break;
   }
 
@@ -796,7 +863,7 @@ error_stack(_cups_ps_stack_t *st,   /* I - Stack */
   _cups_ps_obj_t       *obj;           /* Current object on stack */
 
 
-  _cupsRasterAddError(title);
+  _cupsRasterAddError("%s", title);
 
   for (obj = st->objs, c = st->num_objs; c > 0; c --, obj ++)
     error_object(obj);
@@ -880,7 +947,7 @@ push_stack(_cups_ps_stack_t *st,    /* I - Stack */
 
     st->alloc_objs += 32;
 
-    if ((temp = realloc(st->objs, st->alloc_objs *
+    if ((temp = realloc(st->objs, (size_t)st->alloc_objs *
                                   sizeof(_cups_ps_obj_t))) == NULL)
       return (NULL);
 
@@ -941,12 +1008,12 @@ roll_stack(_cups_ps_stack_t *st, /* I - Stack */
 
     s = -s;
 
-    if ((temp = calloc(s, sizeof(_cups_ps_obj_t))) == NULL)
+    if ((temp = calloc((size_t)s, sizeof(_cups_ps_obj_t))) == NULL)
       return (-1);
 
-    memcpy(temp, st->objs + n, s * sizeof(_cups_ps_obj_t));
-    memmove(st->objs + n, st->objs + n + s, (c - s) * sizeof(_cups_ps_obj_t));
-    memcpy(st->objs + n + c - s, temp, s * sizeof(_cups_ps_obj_t));
+    memcpy(temp, st->objs + n, (size_t)s * sizeof(_cups_ps_obj_t));
+    memmove(st->objs + n, st->objs + n + s, (size_t)(c - s) * sizeof(_cups_ps_obj_t));
+    memcpy(st->objs + n + c - s, temp, (size_t)s * sizeof(_cups_ps_obj_t));
   }
   else
   {
@@ -954,13 +1021,12 @@ roll_stack(_cups_ps_stack_t *st, /* I - Stack */
     * Shift up...
     */
 
-    if ((temp = calloc(s, sizeof(_cups_ps_obj_t))) == NULL)
+    if ((temp = calloc((size_t)s, sizeof(_cups_ps_obj_t))) == NULL)
       return (-1);
 
-    memcpy(temp, st->objs + n + c - s, s * sizeof(_cups_ps_obj_t));
-    memmove(st->objs + n + s, st->objs + n,
-            (c - s) * sizeof(_cups_ps_obj_t));
-    memcpy(st->objs + n, temp, s * sizeof(_cups_ps_obj_t));
+    memcpy(temp, st->objs + n + c - s, (size_t)s * sizeof(_cups_ps_obj_t));
+    memmove(st->objs + n + s, st->objs + n, (size_t)(c - s) * sizeof(_cups_ps_obj_t));
+    memcpy(st->objs + n, temp, (size_t)s * sizeof(_cups_ps_obj_t));
   }
 
   free(temp);
@@ -1079,7 +1145,7 @@ scan_ps(_cups_ps_stack_t *st,             /* I  - Stack */
                ch = (ch << 3) + *cur - '0';
              }
 
-             *valptr++ = ch;
+             *valptr++ = (char)ch;
            }
            else if (*cur == '\r')
            {
@@ -1156,7 +1222,7 @@ scan_ps(_cups_ps_stack_t *st,             /* I  - Stack */
                ch |= tolower(*cur) - 'a' + 10;
             }
 
-           *valptr++ = ch;
+           *valptr++ = (char)ch;
           }
 
           if (*cur != '>')
@@ -1363,7 +1429,7 @@ setpagedevice(
   * Found the start of the dictionary, empty the stack to this point...
   */
 
-  st->num_objs = obj - st->objs;
+  st->num_objs = (int)(obj - st->objs);
 
  /*
   * Now pull /name and value pairs from the dictionary...
@@ -1660,5 +1726,5 @@ DEBUG_stack(_cups_ps_stack_t *st) /* I - Stack */
 
 
 /*
- * End of "$Id: interpret.c 7852 2008-08-21 04:19:45Z mike $".
+ * End of "$Id$".
  */