Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct PPD gets uploaded as incorrect PPD #1929

Closed
michaelrsweet opened this Issue Aug 23, 2006 · 3 comments

Comments

Projects
None yet
1 participant
@michaelrsweet
Copy link
Collaborator

michaelrsweet commented Aug 23, 2006

Version: 1.2.2
CUPS.org User: twaugh.redhat

The copy_model() function (see scheduler/ipp.c:4129) copies PPD defaults from the original PPD into the new PPD, and does this even for enums that have no matching option choice. This causes the PPD to fail cupstestppd, and can have all sorts of bad effects.

The real-life example is the InputSlot option. One PPD might have a 'Middle' option choice, and it may even be the default, but another may not have a 'Middle' InputSlot option choice at all. But uploading a new PPD in place of the 'Middle'-InputSlot PPD will result in a PPD where 'Middle' is selected but is not a choice.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

michaelrsweet commented Aug 23, 2006

CUPS.org User: mike

I'm not sure what we'll do about this; we don't have a list of the available options in the new PPD, so we'll need to save the (possibly generated) PPD to a temp file, open it with ppdOpenFile(), and then use it to validate the old default choice for every option.

This will not get fixed for 1.2.3, but definitely for a later 1.2.x release.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

michaelrsweet commented Oct 12, 2006

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

michaelrsweet commented Oct 12, 2006

"str1929.patch":

Index: ipp.c

--- ipp.c (revision 6027)
+++ ipp.c (working copy)
@@ -74,7 +74,6 @@

  • get_username() - Get the username associated with a request.
  • hold_job() - Hold a print job.
  • move_job() - Move a job to a new destination.
  • * ppd_add_default() - Add a PPD default choice.
  • ppd_parse_line() - Parse a PPD default line.
  • print_job() - Print a file to a printer or class.
  • read_ps_line() - Read a line from a PS file...
    @@ -116,17 +115,6 @@

/*

  • * PPD default choice structure...

- */

-typedef struct
-{

  • char option[PPD_MAX_NAME]; /* Main keyword (option name) */
  • char choice[PPD_MAX_NAME]; /* Option keyword (choice name) /
    -} ppd_default_t;
    -
    -
    -/
  • Local functions...
    */

@@ -185,8 +173,6 @@
static const char *get_username(cupsd_client_t *con);
static void hold_job(cupsd_client_t *con, ipp_attribute_t *uri);
static void move_job(cupsd_client_t *con, ipp_attribute_t *uri);
-static int ppd_add_default(const char *option, const char *choice,

  •                   int num_defaults, ppd_default_t *_defaults);
    
    static int ppd_parse_line(const char *line, char *option, int olen,
    char *choice, int clen);
    static void print_job(cupsd_client_t *con, ipp_attribute_t *uri);
    @@ -3784,15 +3770,15 @@
    *envp[MAX_ENV]; /_ Environment /
    cups_file_t *src, /
    Source file /
    *dst; /
    Destination file */
  • ppd_file_t ppd; / PPD file /
    int bytes, /
    Bytes from pipe /
    total; /
    Total bytes from pipe */
  • char buffer[2048], /* Copy buffer */
  •   _ptr;           /_ Pointer into buffer */
    
  • char buffer[2048]; /* Copy buffer /
    int i; /
    Looping var /
    char option[PPD_MAX_NAME], /
    Option name /
    choice[PPD_MAX_NAME]; /
    Choice name /
    int num_defaults; /
    Number of default options */
  • ppd_default_t defaults; / Default options */
  • cups_option_t defaults; / Default options /
    char cups_protocol[PPD_MAX_LINE];
    /
    cupsProtocol attribute /
    int have_letter, /
    Have Letter size */
    @@ -3933,42 +3919,15 @@
  • Read the source file and see what page sizes are supported...
    */
  • if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
  • if ((ppd = ppdOpenFile(tempfile)) == NULL)
    {
    unlink(tempfile);
    return (-1);
    }
  • have_letter = 0;
  • have_a4 = 0;
  • have_letter = ppdPageSize(ppd, "Letter") != NULL;
  • have_a4 = ppdPageSize(ppd, "A4") != NULL;
  • while (cupsFileGets(src, buffer, sizeof(buffer)))
  • if (!strncmp(buffer, "*PageSize ", 10))
  • {
  • /*
    
  •  \* Strip UI text and command data from the end of the line...
    

- */

  •  if ((ptr = strchr(buffer + 10, '/')) != NULL)
    
  •    *ptr = '\0';
    
  •  if ((ptr = strchr(buffer + 10, ':')) != NULL)
    

- *ptr = '\0';

- for (ptr = buffer + 10; isspace(*ptr); ptr ++);

  • /*
    
  •  \* Look for Letter and A4 page sizes...
    

- */

  •  if (!strcmp(ptr, "Letter"))
    

- have_letter = 1;

  •  if (!strcmp(ptr, "A4"))
    
  • have_a4 = 1;

- }

- cupsFileRewind(src);

/*

  • Open the destination (if possible) and set the default options...
    */
    @@ -3992,8 +3951,21 @@

     if (!ppd_parse_line(buffer, option, sizeof(option),
                    choice, sizeof(choice)))
    
    •      num_defaults = ppd_add_default(option, choice, num_defaults,
      
    •    {
      
    • ppd_option_t  _ppdo;      /_ PPD option */
      
    •     /*
      
    • \* Only add the default if the default hasn't already been
      
    • \* set and the choice exists in the new PPD...
      
    • */
      
    • if (!cupsGetOption(option, num_defaults, defaults) &&
      
    •     (ppdo = ppdFindOption(ppd, option)) != NULL &&
      
    •     ppdFindChoice(ppdo, choice))
      
    •        num_defaults = cupsAddOption(option, choice, num_defaults,
                               &defaults);
      
    •    }
      
      }
      else if (!strncmp(buffer, "*cupsProtocol:", 14))
      strlcpy(cups_protocol, buffer, sizeof(cups_protocol));
      @@ -4039,6 +4011,7 @@
      !strcasecmp(DefaultLanguage, "C") ||
      !strcasecmp(DefaultLanguage, "POSIX") ||
      !strcasecmp(DefaultLanguage, "en") ||
    • !strncasecmp(DefaultLanguage, "en.", 3) ||
      !strncasecmp(DefaultLanguage, "en_US", 5) ||
      !strncasecmp(DefaultLanguage, "en_CA", 5) ||
      !strncasecmp(DefaultLanguage, "fr_CA", 5))
      @@ -4049,14 +4022,14 @@

    if (have_letter)
    {

    • num_defaults = ppd_add_default("PageSize", "Letter", num_defaults,
    •                                   &defaults);
      
    • num_defaults = ppd_add_default("PageRegion", "Letter", num_defaults,
    •                                   &defaults);
      
    • num_defaults = ppd_add_default("PaperDimension", "Letter", num_defaults,
    •                                   &defaults);
      
    • num_defaults = ppd_add_default("ImageableArea", "Letter", num_defaults,
    •                                   &defaults);
      
    • num_defaults = cupsAddOption("PageSize", "Letter", num_defaults,
    •                                 &defaults);
      
    • num_defaults = cupsAddOption("PageRegion", "Letter", num_defaults,
    •                                 &defaults);
      
    • num_defaults = cupsAddOption("PaperDimension", "Letter", num_defaults,
    •                                 &defaults);
      
    • num_defaults = cupsAddOption("ImageableArea", "Letter", num_defaults,
    •                                 &defaults);
      
      }
      }
      else if (have_a4)
      @@ -4065,26 +4038,37 @@
      • The rest default to "a4" size...
        */
  •  num_defaults = ppd_add_default("PageSize", "A4", num_defaults,
    
  •                                 &defaults);
    
  •  num_defaults = ppd_add_default("PageRegion", "A4", num_defaults,
    
  •                                 &defaults);
    
  •  num_defaults = ppd_add_default("PaperDimension", "A4", num_defaults,
    
  •                                 &defaults);
    
  •  num_defaults = ppd_add_default("ImageableArea", "A4", num_defaults,
    
  •                                 &defaults);
    
  •  num_defaults = cupsAddOption("PageSize", "A4", num_defaults,
    
  •                               &defaults);
    
  •  num_defaults = cupsAddOption("PageRegion", "A4", num_defaults,
    
  •                               &defaults);
    
  •  num_defaults = cupsAddOption("PaperDimension", "A4", num_defaults,
    
  •                               &defaults);
    
  •  num_defaults = cupsAddOption("ImageableArea", "A4", num_defaults,
    
  •                               &defaults);
    

    }
    }

  • ppdClose(ppd);

/*

  • * Open the source file for a copy...
  • */
  • if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
  • {
  • cupsFreeOptions(num_defaults, defaults);
  • unlink(tempfile);
  • return (-1);
  • }
  • /*

    • Open the destination file for a copy...
      */

    if ((dst = cupsFileOpen(to, "wb")) == NULL)
    {

  • if (num_defaults > 0)

- free(defaults);

  • cupsFreeOptions(num_defaults, defaults);
    cupsFileClose(src);
    unlink(tempfile);
    return (-1);
    @@ -4105,17 +4089,17 @@
    if (!ppd_parse_line(buffer, option, sizeof(option),
    choice, sizeof(choice)))
    {
  •    for (i = 0; i < num_defaults; i ++)
    
  • if (!strcmp(option, defaults[i].option))
    
  • {
    
  •  /*
    
  •   \* Substitute the previous choice...
    
  •   */
    
  •    const char *val;       /* Default option value */
    
  •   snprintf(buffer, sizeof(buffer), "*Default%s: %s", option,
    
  •            defaults[i].choice);
    
  •   break;
    
  • }
    
  •    if ((val = cupsGetOption(option, num_defaults, defaults)) != NULL)
    
  • {
  • /*
  • \* Substitute the previous choice...
    
  • */
    
  • snprintf(buffer, sizeof(buffer), "*Default%s: %s", option, val);
    
  • }
    }
    }

@@ -4125,8 +4109,7 @@
if (cups_protocol[0])
cupsFilePrintf(dst, "%s\n", cups_protocol);

  • if (num_defaults > 0)
  • free(defaults);
  • cupsFreeOptions(num_defaults, defaults);

/*

  • Close both files and return...
    @@ -6537,56 +6520,6 @@

/*

  • * 'ppd_add_default()' - Add a PPD default choice.

- */

-static int /* O - Number of defaults */
-ppd_add_default(

  • const char option, / I - Option name */
  • const char choice, / I - Choice name */
  • int num_defaults, /* I - Number of defaults */
  • ppd_default_t *defaults) / IO - Defaults */
    -{
  • int i; /* Looping var */

- ppd_default_t temp; / Temporary defaults array */

  • /*
  • * First check if the option already has a default value; the PPD spec
  • * says that the first one is used...

- */

  • for (i = 0, temp = *defaults; i < num_defaults; i ++)
  • if (!strcmp(option, temp[i].option))

- return (num_defaults);

  • /*
  • * Now add the option...

- */

  • if (num_defaults == 0)
  • temp = malloc(sizeof(ppd_default_t));
  • else

- temp = realloc(*defaults, (num_defaults + 1) * sizeof(ppd_default_t));

  • if (!temp)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "ppd_add_default: Unable to add default value for "%s" - %s",
  •           option, strerror(errno));
    
  • return (num_defaults);

- }

  • *defaults = temp;

- temp += num_defaults;

  • strlcpy(temp->option, option, sizeof(temp->option));

- strlcpy(temp->choice, choice, sizeof(temp->choice));

  • return (num_defaults + 1);
    -}

-/*

  • 'ppd_parse_line()' - Parse a PPD default line.
    */

@michaelrsweet 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
You can’t perform that action at this time.