Skip to content

Commit

Permalink
Overtaken patches from Debian package of CUPS
Browse files Browse the repository at this point in the history
1. Fix conversion of PPD option choice names to IPP attributes

When I create a CUPS queue with a PPD file with choice names "Tray-1",
"Tray-2", ... in the InputSlot option CUPS translates these names to
double-dashed IPP attribute names: "tray--1", "tray--2", ... in the
"media-source" attribute, both when passing a job to the printer with
the IPP backend, making the printer ignore the tray choice, and also
when answering a get-printer-attributes IPP request from a
client. This happens when in the PPD a dash is followed by a digit, as
the pwg_unppdize_name() function in cups/ppd-cache.c inserts a dash
whenever a non-digit is followed by a digit in the PPD name. As IPP
attribute names generally never have double-dashes and also no dashes
in the beginning or the end of the name, I have modified the
pwg_unppdize_name() function appropriately.

Upstream bug: apple/cups#5740
Debian bug: https://bugs.debian.org/949315

2. Fix scheduler's cupsd.conf load (triggered by cupsctl and web interface)

When running it without arguments it is supposed to read the local
CUPS's cupsd.conf and show a summary of the setting. in CUPS 2.3.1 it
shows a mess with a lot of HTML inside and this is due to the fact
that when loading the file via HTTP using the /admin/cups/cupsd.conf
path the scheduler calls the admin.cgi program which returns the admin
front page of the web admin interface. cupsctl then tries to interpret
that as the config file and displays garbage. Even worse is if you run
cupsctl with command line argument (one of the five switches or a
key=value pair) to change a setting. It seems to load cupsd.conf again
and gets again the HTML code of the web interface page.  cupsctl tries
to interpret this again, producing garbage, adds the user-supplied
setting and writes all this back into cupsd.conf. Then it tries to
restart the scheduler which fails due to the broken config file.  The
problem is that in the file scheduler/client.conf, in the function
get_file() the URI from the client is at first checked whether it
begins with "/admin/" and in this case the CGI program admin.cgi is
responsible. Only after that the check for "/admin/conf/cupsd.conf"
comes and is never reached.  I have changed the order now
appropriately and this way cupsctl works again.  Note that the problem
only occurs if the web interface is active and the cupsctl command is
issued by a non-root user.  This is a regression caused by issue

Upstream bug: apple/cups#5744
  • Loading branch information
tillkamppeter committed May 7, 2020
1 parent d6faf26 commit db37902
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 0 deletions.
86 changes: 86 additions & 0 deletions patches/cupsd-fix-load-cupsd.conf.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
From: Till Kamppeter <till.kamppeter@gmail.com>
Date: Sat, 22 Feb 2020 14:28:58 +0100
Subject: Fix scheduler cupsd.conf load

When running it without arguments it is supposed to read the local CUPS's
cupsd.conf and show a summary of the setting. in CUPS 2.3.1 it shows a mess
with a lot of HTML inside and this is due to the fact that when loading the
file via HTTP using the /admin/cups/cupsd.conf path the scheduler calls the
admin.cgi program which returns the admin front page of the web admin
interface. cupsctl then tries to interpret that as the config file and displays
garbage. Even worse is if you run cupsctl with command line argument (one of
the five switches or a key=value pair) to change a setting. It seems to load
cupsd.conf again and gets again the HTML code of the web interface page.
cupsctl tries to interpret this again, producing garbage, adds the
user-supplied setting and writes all this back into cupsd.conf. Then it tries
to restart the scheduler which fails due to the broken config file.
The problem is that in the file scheduler/client.conf, in the function
get_file() the URI from the client is at first checked whether it begins with
"/admin/" and in this case the CGI program admin.cgi is responsible. Only after
that the check for "/admin/conf/cupsd.conf" comes and is never reached.
I have changed the order now appropriately and this way cupsctl works again.
Note that the problem only occurs if the web interface is active and the
cupsctl command is issued by a non-root user.
This is a regression caused by issue #5652.

Bug: https://github.com/apple/cups/issues/5744
---
scheduler/client.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/scheduler/client.c b/scheduler/client.c
index c2ee8f1..54b841b 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -2789,6 +2789,25 @@ get_file(cupsd_client_t *con, /* I - Client connection */

perm_check = 0;
}
+ else if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
+ {
+ strlcpy(filename, ConfigurationFile, len);
+
+ perm_check = 0;
+ }
+ else if (!strncmp(con->uri, "/admin/log/", 11))
+ {
+ if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/')
+ strlcpy(filename, AccessLog, len);
+ else if (!strncmp(con->uri + 11, "error_log", 9) && ErrorLog[0] == '/')
+ strlcpy(filename, ErrorLog, len);
+ else if (!strncmp(con->uri + 11, "page_log", 8) && PageLog[0] == '/')
+ strlcpy(filename, PageLog, len);
+ else
+ return (NULL);
+
+ perm_check = 0;
+ }
else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/jobs", 5) || !strncmp(con->uri, "/printers", 9))
{
/*
@@ -2822,25 +2841,6 @@ get_file(cupsd_client_t *con, /* I - Client connection */

perm_check = 0;
}
- else if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
- {
- strlcpy(filename, ConfigurationFile, len);
-
- perm_check = 0;
- }
- else if (!strncmp(con->uri, "/admin/log/", 11))
- {
- if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/')
- strlcpy(filename, AccessLog, len);
- else if (!strncmp(con->uri + 11, "error_log", 9) && ErrorLog[0] == '/')
- strlcpy(filename, ErrorLog, len);
- else if (!strncmp(con->uri + 11, "page_log", 8) && PageLog[0] == '/')
- strlcpy(filename, PageLog, len);
- else
- return (NULL);
-
- perm_check = 0;
- }
else if (con->language)
{
snprintf(language, sizeof(language), "/%s", con->language->language);
99 changes: 99 additions & 0 deletions patches/libcups-fix-convert-option-choice-names-in-ppd.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
From: Till Kamppeter <till.kamppeter@gmail.com>
Date: Mon, 17 Feb 2020 09:05:58 +0100
Subject: Fix conversion of PPD InputSlot choice names

When I create a CUPS queue with a PPD file with choice names "Tray-1", "Tray-2",
... in the InputSlot option CUPS translates these names to double-dashed IPP
attribute names: "tray--1", "tray--2", ... in the "media-source" attribute, both
when passing a job to the printer with the IPP backend, making the printer
ignore the tray choice, and also when answering a get-printer-attributes IPP
request from a client. This happens when in the PPD a dash is followed by a
digit, as the pwg_unppdize_name() function in cups/ppd-cache.c inserts a dash
whenever a non-digit is followed by a digit in the PPD name. As IPP attribute
names generally never have double-dashes and also no dashes in the beginning or
the end of the name, I have modified the pwg_unppdize_name() function
appropriately.

Bug: https://github.com/apple/cups/issues/5740
Bug-Debian: https://bugs.debian.org/949315
---
cups/ppd-cache.c | 47 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c
index 5965e38..6609f53 100644
--- a/cups/ppd-cache.c
+++ b/cups/ppd-cache.c
@@ -5140,6 +5140,8 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
{
char *ptr, /* Pointer into name buffer */
*end; /* End of name buffer */
+ int nodash = 1; /* Next char in IPP name cannot be a
+ dash (first char or after a dash) */


if (_cups_islower(*ppd))
@@ -5151,7 +5153,9 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
const char *ppdptr; /* Pointer into PPD keyword */

for (ppdptr = ppd + 1; *ppdptr; ppdptr ++)
- if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr))
+ if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr) ||
+ (*ppdptr == '-' && *(ppdptr - 1) == '-') ||
+ (*ppdptr == '-' && *(ppdptr + 1) == '\0'))
break;

if (!*ppdptr)
@@ -5163,19 +5167,44 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */

for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++)
{
- if (_cups_isalnum(*ppd) || *ppd == '-')
+ if (_cups_isalnum(*ppd))
+ {
*ptr++ = (char)tolower(*ppd & 255);
- else if (strchr(dashchars, *ppd))
- *ptr++ = '-';
+ nodash = 0;
+ }
+ else if (*ppd == '-' || strchr(dashchars, *ppd))
+ {
+ if (nodash == 0)
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ }
else
+ {
*ptr++ = *ppd;
+ nodash = 0;
+ }

- if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
- _cups_isupper(ppd[1]) && ptr < end)
- *ptr++ = '-';
- else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255))
- *ptr++ = '-';
+ if (nodash == 0)
+ {
+ if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
+ _cups_isupper(ppd[1]) && ptr < end)
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255))
+ {
+ *ptr++ = '-';
+ nodash = 1;
+ }
+ }
}

+ /* Remove trailing dashes */
+ while (ptr > name && *(ptr - 1) == '-')
+ ptr --;
+
*ptr = '\0';
}
2 changes: 2 additions & 0 deletions snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ parts:
patch -p0 < $SNAPCRAFT_STAGE/patches/cups-deviced-allow-run-by-root.patch
patch -p1 < $SNAPCRAFT_STAGE/patches/cups-airprint-support.patch
patch -p1 < $SNAPCRAFT_STAGE/patches/cupsd-extra-check-for-admin-tasks-snap-cups-control.patch
patch -p1 < $SNAPCRAFT_STAGE/patches/libcups-fix-convert-option-choice-names-in-ppd.patch
patch -p1 < $SNAPCRAFT_STAGE/patches/cupsd-fix-load-cupsd.conf.patch
sed -i 's|fchown(cupsFileNumber(fp), getuid(), Group)|0|g' scheduler/file.c
sed -i 's|(fchmod(cupsFileNumber(fp), mode))|(0)|g' scheduler/file.c
sed -i 's|chown(filename, user, group)|0|g' scheduler/conf.c
Expand Down

0 comments on commit db37902

Please sign in to comment.