ppd parser should tolerate spaces after main keywords #212

Closed
michaelrsweet opened this Issue Aug 1, 2003 · 7 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Aug 1, 2003

Version: 1.1.20rc1
CUPS.org User: jlovell

There are many PPDs installed in the world that have whitespace between a main keyword and the following colon or slash. With the tightened parser in 1.1.20 these files aren't usable. It'd be nice if people who update their cups version won't be forced to find updated PPDs for the ones they already have. Ideally libcups would tolerated this common problem while still having cupstestppd complain about it.
Thanks!

Collaborator

michaelrsweet commented Aug 1, 2003

CUPS.org User: mike

Unfortunately, if we allow whitespace before the colon in the CUPS API, there is no way for the cupstestppd program to detect it via the API.

I suppose we could add a global "strictness" setting which could be used to do additional validation, however I'm not sure of the usefulness...

Collaborator

michaelrsweet commented Aug 1, 2003

CUPS.org User: jlovell

The usefulness is people won't be surprised to find that their printer stopped working when they update the OS and/or CUPS.

For the time being I've add a global ppd_relaxed_parsing int that cupstestppd could clear before starting it's work (although I made it a static expecting I'll add a function to control it later).

Thanks!

Collaborator

michaelrsweet commented Aug 1, 2003

CUPS.org User: mike

OK, try the attached patch; it adds a new ppdSetConformance() function (PPD_CONFORM_RELAXED and PPD_CONFORM_STRICT are the possible arguments) and defaults to RELAXED.

The updated code barfs of CTRL-Z, lines containing only whitespace, * on a line by itself, whitespace before ':', etc. in strict mode, and ignores it all in relaxed mode.

Collaborator

michaelrsweet commented Aug 1, 2003

CUPS.org User: jlovell

The change looks good but it still fails on some of ppds it used to parse. The attached patch fixes the rest of these.

Thanks again.

Collaborator

michaelrsweet commented Aug 2, 2003

CUPS.org User: mike

Thanks, I've applied your patch to CVS as well.

Collaborator

michaelrsweet commented Aug 2, 2003

"str212.patch":

Index: cups/ppd.c

RCS file: /development/cvs/cups/cups/ppd.c,v
retrieving revision 1.109
diff -u -r1.109 ppd.c
--- cups/ppd.c 2003/07/20 12:42:32 1.109
+++ cups/ppd.c 2003/08/01 14:54:03
@@ -41,6 +41,7 @@

  • ppdOpen() - Read a PPD file into memory.
  • ppdOpenFd() - Read a PPD file into memory.
  • ppdOpenFile() - Read a PPD file into memory.
  • * ppdSetConformance() - Set the conformance level for PPD files.
  • ppd_add_attr() - Add an attribute to the PPD data.
  • ppd_add_choice() - Add a choice to an option.
  • ppd_add_size() - Add a page size.
    @@ -96,6 +97,8 @@
    static ppd_status_t ppd_status = PPD_OK;
    /* Status of last ppdOpen_() */
    static int ppd_line = 0; /_ Current line number */
    +static ppd_conform_t ppd_conform = PPD_CONFORM_RELAXED;
  •               /\* Level of conformance required */
    

/*
@@ -309,11 +312,12 @@
"Illegal control character",
"Illegal main keyword string",
"Illegal option keyword string",

  •     "Illegal translation string"
    
  •     "Illegal translation string",
    
  •     "Illegal whitespace character"
    
    };
  • if (status < PPD_OK || status > PPD_ILLEGAL_TRANSLATION)
  • if (status < PPD_OK || status > PPD_ILLEGAL_WHITESPACE)
    return ("Unknown");
    else
    return (messages[status]);
    @@ -1757,6 +1761,17 @@

/*

  • * 'ppdSetConformance()' - Set the conformance level for PPD files.
  • /
    +
    +void
    +ppdSetConformance(ppd_conform_t c) /
    I - Conformance level */
    +{
  • ppd_conform = c;
    +}

+/*

  • 'ppd_add_attr()' - Add an attribute to the PPD data.
    */

@@ -2242,7 +2257,7 @@

*lineptr++ = '\n';
   }
  •  else if (ch < ' ' && ch != '\t' && ch != 0x1a)
    
  •  else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
    

    {
    /*
    * Other control characters...
    @@ -2310,7 +2325,7 @@

    ch = '\n';
    }

  • else if (ch < ' ' && ch != '\t' && ch != 0x1a)

  • else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
    {
    /*
    * Other control characters...
    @@ -2369,7 +2384,7 @@

    break;
    }

  • else if (ch < ' ' && ch != '\t' && ch != 0x1a)

  • else if (ch < ' ' && ch != '\t' && ppd_conform == PPD_CONFORM_STRICT)
    {
    /*
    * Other control characters...
    @@ -2421,7 +2436,6 @@
    *string = NULL;

if (!line[0] || /* Blank line */

  •    strcmp(line, "*") == 0 ||  /* (Bad) comment line */
     strncmp(line, "*%", 2) == 0 || /* Comment line */
     strcmp(line, "*End") == 0) /* End of multi-line string */
    

    {
    @@ -2429,8 +2443,30 @@
    continue;
    }

  • if (strcmp(line, "") == 0) / (Bad) comment line */

  • {

  •  if (ppd_conform == PPD_CONFORM_RELAXED)
    
  •  {
    
  • startline = ppd_line + 1;

  • continue;

  •  }
    
  •  else
    
  •  {
    
  •    ppd_line   = startline;
    
  •    ppd_status = PPD_ILLEGAL_MAIN_KEYWORD;
    
  •    return (0);
    
  •  }
    
  • }

if (line[0] != '') / All lines start with an asterisk */
{

  •  if (ppd_conform == PPD_CONFORM_STRICT)
    
  •  {
    
  •    ppd_status = PPD_MISSING_ASTERISK;
    
  •    return (0);
    
  •  }
    
    • /*
    • Allow lines consisting of just whitespace...
      */
      @@ -2500,6 +2536,13 @@
      }

      *optptr = '\0';
      +

  •  if (!option[0] && ppd_conform == PPD_CONFORM_STRICT)
    
  •  {
    
  •    ppd_status = PPD_ILLEGAL_WHITESPACE;
    
  • return (0);

  •  }
    
    • mask |= PPD_OPTION;

    /* DEBUG_printf(("option = "%s", lineptr = "%s"\n", option, lineptr));/
    @@ -2535,13 +2578,23 @@
    /
    DEBUG_printf(("text = "%s", lineptr = "%s"\n", text, lineptr));*/
    }

  • if (isspace(*lineptr) && ppd_conform == PPD_CONFORM_STRICT)

  • {

  •  ppd_status = PPD_ILLEGAL_WHITESPACE;
    
  •  return (0);
    
  • }

  • while (isspace(*lineptr))

  •  lineptr ++;
    

    if (lineptr == ':')
    {
    /

    • Get string after triming leading and trailing whitespace...
      */
  •  while (*lineptr == ':' || isspace(*lineptr))
    
  •  lineptr ++;
    
  •  while (isspace(*lineptr))
     lineptr ++;
    

    strptr = lineptr + strlen(lineptr) - 1;

    Index: cups/ppd.h

    RCS file: /development/cvs/cups/cups/ppd.h,v
    retrieving revision 1.35
    diff -u -r1.35 ppd.h
    --- cups/ppd.h 2003/04/10 12:57:41 1.35
    +++ cups/ppd.h 2003/08/01 14:54:03
    @@ -120,9 +120,16 @@
    PPD_ILLEGAL_CHARACTER, /* Illegal control character /
    PPD_ILLEGAL_MAIN_KEYWORD, /
    Illegal main keyword string /
    PPD_ILLEGAL_OPTION_KEYWORD, /
    Illegal option keyword string */

  • PPD_ILLEGAL_TRANSLATION /* Illegal translation string */

  • PPD_ILLEGAL_TRANSLATION, /* Illegal translation string */

  • PPD_ILLEGAL_WHITESPACE /* Illegal whitespace character */
    } ppd_status_t;

+typedef enum /**** Conformance Levels ****/
+{

  • PPD_CONFORM_RELAXED, /* Relax whitespace and control char */
  • PPD_CONFORM_STRICT /* Require strict conformance _/
    +} ppd_conform_t;

typedef struct /*** PPD Attribute Structure ***/
{
char name[PPD_MAX_NAME],
@@ -312,6 +319,9 @@
extern ppd_attr_t *ppdFindNextAttr(ppd_file_t *ppd, const char *name,
const char *spec);
extern ppd_status_t ppdLastError(int *line);
+
+/**_* New in CUPS 1.1.20 ****/
+extern void ppdSetConformance(ppd_conform_t c);

/*

Index: systemv/cupstestppd.c

RCS file: /development/cvs/cups/systemv/cupstestppd.c,v
retrieving revision 1.24
diff -u -r1.24 cupstestppd.c
--- systemv/cupstestppd.c 2003/07/20 02:28:22 1.24
+++ systemv/cupstestppd.c 2003/08/01 14:54:04
@@ -93,12 +93,12 @@
"JCL", "PAGE", "PROLOG" };

- setbuf(stdout, NULL);

/*

  • Display PPD files for each file listed on the command-line...
    */
  • ppdSetConformance(PPD_CONFORM_STRICT);

verbose = 0;
ppd = NULL;
files = 0;
@@ -110,7 +110,7 @@
for (opt = argv[i] + 1; _opt; opt ++)
switch (_opt)
{

  • case 'q' :
    
  • case 'q' :            /* Quiet mode */
      if (verbose > 0)
      {
        fputs("cupstestppd: The -q option is incompatible with the -v option.\n",
    

    @@ -120,8 +120,12 @@

      verbose --;
      break;
    
  • case 'r' :            /\* Relaxed mode */
    
  •          ppdSetConformance(PPD_CONFORM_RELAXED);
    
  •     break;
    
  • case 'v' :
    
  • case 'v' :            /\* Verbose mode */
      if (verbose < 0)
      {
        fputs("cupstestppd: The -v option is incompatible with the -q option.\n",
    

    @@ -1008,8 +1012,8 @@
    void
    usage(void)
    {

  • puts("Usage: cupstestppd [-q] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]");

  • puts(" program | cupstestppd [-q] [-v[v]] -");

  • puts("Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]");

  • puts(" program | cupstestppd [-q] [-r] [-v[v]] -");

exit(ERROR_USAGE);
}

Collaborator

michaelrsweet commented Aug 2, 2003

"str212_2.patch":

Index: cups/ppd.c

RCS file: /home/anoncvs/cups/cups/ppd.c,v
retrieving revision 1.110
diff -u -d -b -w -r1.110 ppd.c
--- cups/ppd.c 1 Aug 2003 14:58:40 -0000 1.110
+++ cups/ppd.c 1 Aug 2003 21:30:23 -0000
@@ -963,7 +963,7 @@
* Don't allow nesting of options...
*/

  •  if (option)
    
  •  if (option && ppd_conform == PPD_CONFORM_STRICT)
    
    {
    ppd_status = PPD_NESTED_OPEN_UI;

@@ -1030,12 +1030,14 @@
option->ui = PPD_UI_BOOLEAN;
else if (string && strcmp(string, "PickOne") == 0)
option->ui = PPD_UI_PICKONE;

  •  else
    
  •  else if (ppd_conform == PPD_CONFORM_STRICT)
    

    {
    ppd_status = PPD_BAD_OPEN_UI;

    goto error;
    }

  •  else
    
  •    option->ui = PPD_UI_PICKONE;
    

    for (j = 0; j < ppd->num_attrs; j ++)
    if (!strncmp(ppd->attrs[j]->name, "Default", 7) &&
    @@ -1086,7 +1088,7 @@

    • Don't allow nesting of options...
      */
  •  if (option)
    
  •  if (option && ppd_conform == PPD_CONFORM_STRICT)
    

    {
    ppd_status = PPD_NESTED_OPEN_UI;

@@ -2522,7 +2524,7 @@

   optptr = option;
  •  while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':' &&
    
  •  while (*lineptr != '\0' && !isspace(*lineptr) && *lineptr != ':' &&
          *lineptr != '/')
    

    {
    if (*lineptr <= ' ' || *lineptr > 126 ||
    @@ -2537,11 +2539,14 @@

    *optptr = '\0';

  •  if (!option[0] && ppd_conform == PPD_CONFORM_STRICT)
    
  •  if (isspace(*lineptr) && ppd_conform == PPD_CONFORM_STRICT)
    

    {
    ppd_status = PPD_ILLEGAL_WHITESPACE;
    return (0);
    }
    +

  •  while (isspace(*lineptr))
    
  • lineptr ++;

    mask |= PPD_OPTION;

michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment