]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
libppd: Improved caching of PPD's page sizes and custom page size limits
authorTill Kamppeter <till.kamppeter@gmail.com>
Wed, 22 Sep 2021 10:24:24 +0000 (12:24 +0200)
committerTill Kamppeter <till.kamppeter@gmail.com>
Wed, 22 Sep 2021 10:24:24 +0000 (12:24 +0200)
1. If an PPD page size has non-standard dimensions, pwgMediaForSize()
returns "custom_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu" and not NULL, while we
assume that we would get NULL in such a case. So consider "custom_..."
PWG page size names also as a PWG size not having been found. This
gives PWG page size nmaes of "pp_lowerppd_WIDTHxHEIGHTuu" style, much
more useful and the page size not being skipped by PAPPL's web
interface.

2. If the PPD defines a too high demension (something like ~30 m is
enough) for the maximum allowed custom page size, the generated PWG
page size name ("custom_max_WIDTHxHEIGHTuu") contains negative numbers
due to an integer overflow. If this happens, we sanitize the string
now replacing these negative numbers by a high integer value (10000
inches or 100000 mm). This PWG size name is used by PAPPL's web
interface to know about the allowed dimensions for a custom page
size. With a negative value the web interface inserts 0, making the
max dimension smaller than the min and with this clicks on the "Save
Changes" button on the "Media" web interface page of PAPPL are
silently ignored.

ppd/ppd-cache.c

index b8a1c265af2532e3fba8738d6910d2e95b43376c..6f7f874252c39979eef2147615b59ad31f893f2b 100644 (file)
@@ -1176,7 +1176,7 @@ ppdCacheCreateWithPPD(ppd_file_t *ppd)    /* I - PPD file */
          }
       }
 
-      if (pwg_media)
+      if (pwg_media && strncmp(pwg_media->pwg, "custom_", 7) != 0)
       {
        /*
        * Standard name and no conflicts, use it!
@@ -1290,6 +1290,30 @@ ppdCacheCreateWithPPD(ppd_file_t *ppd)   /* I - PPD file */
     pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
                      PWG_FROM_POINTS(ppd->custom_max[0]),
                      PWG_FROM_POINTS(ppd->custom_max[1]), NULL);
+
+    /* Some PPD files have upper limits too large to be treated with
+       int numbers, if we have an overflow (negative result for one
+       dimension) use a fixed, large value instead */
+    char *p1, *p2;
+    char *newmax = (pwg_keyword[strlen(pwg_keyword) - 1] == 'n' ?
+                   "10000" : "100000");
+    p1 = strrchr(pwg_keyword, '_');
+    p1 ++;
+    if (*p1 == '-')
+    {
+      for (p2 = p1; *p2 != 'x'; p2 ++);
+      memmove(p1 + strlen(newmax), p2, strlen(p2) + 1);
+      memmove(p1, newmax, strlen(newmax));
+    }
+    p1 = strrchr(pwg_keyword, 'x');
+    p1 ++;
+    if (*p1 == '-')
+    {
+      for (p2 = p1; *p2 != 'm' && *p2 != 'i'; p2 ++);
+      memmove(p1 + strlen(newmax), p2, strlen(p2) + 1);
+      memmove(p1, newmax, strlen(newmax));
+    }
+
     pc->custom_max_keyword = strdup(pwg_keyword);
     pc->custom_max_width   = PWG_FROM_POINTS(ppd->custom_max[0]);
     pc->custom_max_length  = PWG_FROM_POINTS(ppd->custom_max[1]);