diff -up cups-2.3.3op2/cups/ppd-cache.c.make-model-refact cups-2.3.3op2/cups/ppd-cache.c --- cups-2.3.3op2/cups/ppd-cache.c.make-model-refact 2024-09-30 17:19:35.443100091 +0200 +++ cups-2.3.3op2/cups/ppd-cache.c 2024-09-30 17:24:10.927162954 +0200 @@ -3027,9 +3027,10 @@ _ppdCreateFromIPP(char *buffer, /* I - ipp_t *media_col, /* Media collection */ *media_size; /* Media size collection */ char make[256], /* Make and model */ - *model, /* Model name */ + *mptr, /* Pointer into make and model */ ppdname[PPD_MAX_NAME]; /* PPD keyword */ + const char *model; /* Model name */ int i, j, /* Looping vars */ count, /* Number of values */ bottom, /* Largest bottom margin */ @@ -3090,35 +3091,105 @@ _ppdCreateFromIPP(char *buffer, /* I - } /* - * Standard stuff for PPD file... + * Get a sanitized make and model... */ - cupsFilePuts(fp, "*PPD-Adobe: \"4.3\"\n"); - cupsFilePuts(fp, "*FormatVersion: \"4.3\"\n"); - cupsFilePrintf(fp, "*FileVersion: \"%d.%d\"\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); - cupsFilePuts(fp, "*LanguageVersion: English\n"); - cupsFilePuts(fp, "*LanguageEncoding: ISOLatin1\n"); - cupsFilePuts(fp, "*PSVersion: \"(3010.000) 0\"\n"); - cupsFilePuts(fp, "*LanguageLevel: \"3\"\n"); - cupsFilePuts(fp, "*FileSystem: False\n"); - cupsFilePuts(fp, "*PCFileName: \"ippeve.ppd\"\n"); + if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL && ippValidateAttribute(attr)) + { + /* + * Sanitize the model name to only contain PPD-safe characters. + */ - if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make)); + + for (mptr = make; *mptr; mptr ++) + { + if (*mptr < ' ' || *mptr >= 127 || *mptr == '\"') + { + /* + * Truncate the make and model on the first bad character... + */ + + *mptr = '\0'; + break; + } + } + + while (mptr > make) + { + /* + * Strip trailing whitespace... + */ + + mptr --; + if (*mptr == ' ') + *mptr = '\0'; + } + + if (!make[0]) + { + /* + * Use a default make and model if nothing remains... + */ + + strlcpy(make, "Unknown", sizeof(make)); + } + } else - strlcpy(make, "Unknown Printer", sizeof(make)); + { + /* + * Use a default make and model... + */ + + strlcpy(make, "Unknown", sizeof(make)); + } if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) || !_cups_strncasecmp(make, "Hewlett-Packard ", 16)) { + /* + * Normalize HP printer make and model... + */ + model = make + 16; strlcpy(make, "HP", sizeof(make)); + + if (!_cups_strncasecmp(model, "HP ", 3)) + model += 3; + } + else if ((mptr = strchr(make, ' ')) != NULL) + { + /* + * Separate "MAKE MODEL"... + */ + + while (*mptr && *mptr == ' ') + *mptr++ = '\0'; + + model = mptr; } - else if ((model = strchr(make, ' ')) != NULL) - *model++ = '\0'; else - model = make; + { + /* + * No separate model name... + */ + + model = "Printer"; + } + + /* + * Standard stuff for PPD file... + */ + cupsFilePuts(fp, "*PPD-Adobe: \"4.3\"\n"); + cupsFilePuts(fp, "*FormatVersion: \"4.3\"\n"); + cupsFilePrintf(fp, "*FileVersion: \"%d.%d\"\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); + cupsFilePuts(fp, "*LanguageVersion: English\n"); + cupsFilePuts(fp, "*LanguageEncoding: ISOLatin1\n"); + cupsFilePuts(fp, "*PSVersion: \"(3010.000) 0\"\n"); + cupsFilePuts(fp, "*LanguageLevel: \"3\"\n"); + cupsFilePuts(fp, "*FileSystem: False\n"); + cupsFilePuts(fp, "*PCFileName: \"ippeve.ppd\"\n"); cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make); cupsFilePrintf(fp, "*ModelName: \"%s\"\n", model); cupsFilePrintf(fp, "*Product: \"(%s)\"\n", model);