]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Don't crash on PPD files with no size information.
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 27 Sep 2012 03:33:42 +0000 (03:33 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 27 Sep 2012 03:33:42 +0000 (03:33 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@10616 7a7537e8-13f0-0310-91df-b6672ffda945

cups/ppd-cache.c
cups/testppd.c
scheduler/printers.c

index 0cfd5aa0967e476c3e2da9d1b069dcdad64b4898..2e7a5d626d61361ac94db38046183efc6872e580 100644 (file)
@@ -329,7 +329,7 @@ _ppdCacheCreateWithFile(
        goto create_error;
       }
 
-      if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
+      if ((num_sizes = atoi(value)) < 0 || num_sizes > 65536)
       {
         DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSizes value %d on line "
                      "%d.", num_sizes, linenum));
@@ -337,12 +337,15 @@ _ppdCacheCreateWithFile(
        goto create_error;
       }
 
-      if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+      if (num_sizes > 0)
       {
-        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
-                     num_sizes));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
+       if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+       {
+         DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
+                       num_sizes));
+         _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+         goto create_error;
+       }
       }
     }
     else if (!_cups_strcasecmp(line, "Size"))
@@ -697,148 +700,145 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
   * Copy and convert size data...
   */
 
-  if (ppd->num_sizes == 0)
-  {
-    DEBUG_puts("_ppdCacheCreateWithPPD: No page sizes in PPD.");
-    goto create_error;
-  }
-
-  if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
-  {
-    DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
-                  "_pwg_size_t's.", ppd->num_sizes));
-    goto create_error;
-  }
-
-  for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
-       i > 0;
-       i --, ppd_size ++)
+  if (ppd->num_sizes > 0)
   {
-   /*
-    * Don't copy over custom size...
-    */
-
-    if (!_cups_strcasecmp(ppd_size->name, "Custom"))
-      continue;
-
-   /*
-    * Convert the PPD size name to the corresponding PWG keyword name.
-    */
-
-    if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
+    if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
     {
-     /*
-      * Standard name, do we have conflicts?
-      */
-
-      for (j = 0; j < pc->num_sizes; j ++)
-        if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
-       {
-         pwg_media = NULL;
-         break;
-       }
+      DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                   "_pwg_size_t's.", ppd->num_sizes));
+      goto create_error;
     }
 
-    if (pwg_media)
+    for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
+        i > 0;
+        i --, ppd_size ++)
     {
      /*
-      * Standard name and no conflicts, use it!
+      * Don't copy over custom size...
       */
 
-      pwg_name      = pwg_media->pwg;
-      new_known_pwg = 1;
-    }
-    else
-    {
+      if (!_cups_strcasecmp(ppd_size->name, "Custom"))
+       continue;
+
      /*
-      * Not a standard name; convert it to a PWG vendor name of the form:
-      *
-      *     pp_lowerppd_WIDTHxHEIGHTuu
+      * Convert the PPD size name to the corresponding PWG keyword name.
       */
 
-      pwg_name      = pwg_keyword;
-      new_known_pwg = 0;
+      if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
+      {
+       /*
+       * Standard name, do we have conflicts?
+       */
 
-      pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
-      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
-                      _PWG_FROMPTS(ppd_size->width),
-                      _PWG_FROMPTS(ppd_size->length));
-    }
+       for (j = 0; j < pc->num_sizes; j ++)
+         if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
+         {
+           pwg_media = NULL;
+           break;
+         }
+      }
 
-   /*
-    * If we have a similar paper with non-zero margins then we only want to
-    * keep it if it has a larger imageable area length.  The NULL check is for
-    * dimensions that are <= 0...
-    */
+      if (pwg_media)
+      {
+       /*
+       * Standard name and no conflicts, use it!
+       */
 
-    if ((pwg_media = _pwgMediaForSize(_PWG_FROMPTS(ppd_size->width),
-                                      _PWG_FROMPTS(ppd_size->length))) == NULL)
-      continue;
-
-    new_width      = pwg_media->width;
-    new_length     = pwg_media->length;
-    new_left       = _PWG_FROMPTS(ppd_size->left);
-    new_bottom     = _PWG_FROMPTS(ppd_size->bottom);
-    new_right      = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
-    new_top        = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
-    new_imageable  = new_length - new_top - new_bottom;
-    new_borderless = new_bottom == 0 && new_top == 0 &&
-                     new_left == 0 && new_right == 0;
-
-    for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
-         k > 0 && !similar;
-         k --, old_size ++)
-    {
-      old_imageable  = old_size->length - old_size->top - old_size->bottom;
-      old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
-                      old_size->right == 0 && old_size->top == 0;
-      old_known_pwg  = strncmp(old_size->map.pwg, "oe_", 3) &&
-                      strncmp(old_size->map.pwg, "om_", 3);
-
-      similar = old_borderless == new_borderless &&
-                _PWG_EQUIVALENT(old_size->width, new_width) &&
-               _PWG_EQUIVALENT(old_size->length, new_length);
-
-      if (similar &&
-          (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+       pwg_name      = pwg_media->pwg;
+       new_known_pwg = 1;
+      }
+      else
       {
        /*
-       * The new paper has a larger imageable area so it could replace
-       * the older paper.  Regardless of the imageable area, we always
-       * prefer the size with a well-known PWG name.
+       * Not a standard name; convert it to a PWG vendor name of the form:
+       *
+       *     pp_lowerppd_WIDTHxHEIGHTuu
        */
 
-       new_size = old_size;
-       _cupsStrFree(old_size->map.ppd);
-       _cupsStrFree(old_size->map.pwg);
+       pwg_name      = pwg_keyword;
+       new_known_pwg = 0;
+
+       pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
+       _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
+                        _PWG_FROMPTS(ppd_size->width),
+                        _PWG_FROMPTS(ppd_size->length));
       }
-    }
 
-    if (!similar)
-    {
      /*
-      * The paper was unique enough to deserve its own entry so add it to the
-      * end.
+      * If we have a similar paper with non-zero margins then we only want to
+      * keep it if it has a larger imageable area length.  The NULL check is for
+      * dimensions that are <= 0...
       */
 
-      new_size = pwg_size ++;
-      pc->num_sizes ++;
-    }
+      if ((pwg_media = _pwgMediaForSize(_PWG_FROMPTS(ppd_size->width),
+                                       _PWG_FROMPTS(ppd_size->length))) == NULL)
+       continue;
 
-    if (new_size)
-    {
-     /*
-      * Save this size...
-      */
+      new_width      = pwg_media->width;
+      new_length     = pwg_media->length;
+      new_left       = _PWG_FROMPTS(ppd_size->left);
+      new_bottom     = _PWG_FROMPTS(ppd_size->bottom);
+      new_right      = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
+      new_top        = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
+      new_imageable  = new_length - new_top - new_bottom;
+      new_borderless = new_bottom == 0 && new_top == 0 &&
+                      new_left == 0 && new_right == 0;
+
+      for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
+          k > 0 && !similar;
+          k --, old_size ++)
+      {
+       old_imageable  = old_size->length - old_size->top - old_size->bottom;
+       old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
+                        old_size->right == 0 && old_size->top == 0;
+       old_known_pwg  = strncmp(old_size->map.pwg, "oe_", 3) &&
+                        strncmp(old_size->map.pwg, "om_", 3);
+
+       similar = old_borderless == new_borderless &&
+                 _PWG_EQUIVALENT(old_size->width, new_width) &&
+                 _PWG_EQUIVALENT(old_size->length, new_length);
+
+       if (similar &&
+           (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+       {
+        /*
+         * The new paper has a larger imageable area so it could replace
+         * the older paper.  Regardless of the imageable area, we always
+         * prefer the size with a well-known PWG name.
+         */
 
-      new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
-      new_size->map.pwg = _cupsStrAlloc(pwg_name);
-      new_size->width   = new_width;
-      new_size->length  = new_length;
-      new_size->left    = new_left;
-      new_size->bottom  = new_bottom;
-      new_size->right   = new_right;
-      new_size->top     = new_top;
+         new_size = old_size;
+         _cupsStrFree(old_size->map.ppd);
+         _cupsStrFree(old_size->map.pwg);
+       }
+      }
+
+      if (!similar)
+      {
+       /*
+       * The paper was unique enough to deserve its own entry so add it to the
+       * end.
+       */
+
+       new_size = pwg_size ++;
+       pc->num_sizes ++;
+      }
+
+      if (new_size)
+      {
+       /*
+       * Save this size...
+       */
+
+       new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
+       new_size->map.pwg = _cupsStrAlloc(pwg_name);
+       new_size->width   = new_width;
+       new_size->length  = new_length;
+       new_size->left    = new_left;
+       new_size->bottom  = new_bottom;
+       new_size->right   = new_right;
+       new_size->top     = new_top;
+      }
     }
   }
 
index 31ffa050957c5ba3905438b03977621146feecf1..aa4a060684d33d8959d032400f1ead5d6bb883f0 100644 (file)
@@ -150,6 +150,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
                maxsize,                /* Maximum size */
                *size;                  /* Current size */
   ppd_attr_t   *attr;                  /* Current attribute */
+  _ppd_cache_t *pc;                    /* PPD cache */
 
 
   status = 0;
@@ -1073,6 +1074,15 @@ main(int  argc,                          /* I - Number of command-line arguments */
           attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
         printf("    *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
               attr->text, attr->value ? attr->value : "");
+
+      puts("\nPPD Cache:");
+      if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
+        printf("    Unable to create: %s\n", cupsLastErrorString());
+      else
+      {
+        _ppdCacheWriteFile(pc, "t.cache", NULL);
+        puts("    Wrote t.cache.");
+      }
     }
 
     if (!strncmp(argv[1], "-d", 2))
index cd4bd4523bb3ec3907eedb8e20427e5cd62113cc..aeb0332755aa6f6759d28d16be4f2409c3bc8a28 100644 (file)
@@ -3829,6 +3829,10 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
 
     p->pc = _ppdCacheCreateWithPPD(ppd);
 
+    if (!p->pc)
+      cupsdLogMessage(CUPSD_LOG_WARN, "Unable to create cache of \"%s\": %s",
+                      ppd_name, cupsLastErrorString());
+
     ppdMarkDefaults(ppd);
 
     if (ppd->color_device)
@@ -3844,15 +3848,15 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
     ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "color-supported",
                  ppd->color_device);
 
-    if (p->pc->account_id)
+    if (p->pc && p->pc->account_id)
       ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "job-account-id-supported",
                     1);
 
-    if (p->pc->accounting_user_id)
+    if (p->pc && p->pc->accounting_user_id)
       ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER,
                     "job-accounting-user-id-supported", 1);
 
-    if (p->pc->password)
+    if (p->pc && p->pc->password)
     {
       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                    "job-password-encryption-supported", NULL, "none");
@@ -4363,7 +4367,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
     * Mandatory job attributes, if any...
     */
 
-    if (cupsArrayCount(p->pc->mandatory) > 0)
+    if (p->pc && cupsArrayCount(p->pc->mandatory) > 0)
     {
       int      count = cupsArrayCount(p->pc->mandatory);
                                        /* Number of mandatory attributes */