* Definitions...
*/
-#define ppd_free(p) if (p) free(p) /* Safe free macro */
-
#define PPD_KEYWORD 1 /* Line contained a keyword */
#define PPD_OPTION 2 /* Line contained an option name */
#define PPD_TEXT 4 /* Line contained human-readable text */
* Free all strings at the top level...
*/
- _cupsStrFree(ppd->lang_encoding);
- _cupsStrFree(ppd->nickname);
- if (ppd->patches)
- free(ppd->patches);
- _cupsStrFree(ppd->jcl_begin);
- _cupsStrFree(ppd->jcl_end);
- _cupsStrFree(ppd->jcl_ps);
+ free(ppd->lang_encoding);
+ free(ppd->nickname);
+ free(ppd->patches);
+ free(ppd->emulations);
+ free(ppd->jcl_begin);
+ free(ppd->jcl_end);
+ free(ppd->jcl_ps);
/*
* Free any UI groups, subgroups, and options...
for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
ppd_free_group(group);
- ppd_free(ppd->groups);
+ free(ppd->groups);
}
cupsArrayDelete(ppd->options);
*/
if (ppd->num_sizes > 0)
- ppd_free(ppd->sizes);
+ free(ppd->sizes);
/*
* Free any constraints...
*/
if (ppd->num_consts > 0)
- ppd_free(ppd->consts);
+ free(ppd->consts);
/*
* Free any filters...
if (ppd->num_fonts > 0)
{
for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++)
- _cupsStrFree(*font);
+ free(*font);
- ppd_free(ppd->fonts);
+ free(ppd->fonts);
}
/*
*/
if (ppd->num_profiles > 0)
- ppd_free(ppd->profiles);
+ free(ppd->profiles);
/*
* Free any attributes...
{
for (i = ppd->num_attrs, attr = ppd->attrs; i > 0; i --, attr ++)
{
- _cupsStrFree((*attr)->value);
- ppd_free(*attr);
+ free((*attr)->value);
+ free(*attr);
}
- ppd_free(ppd->attrs);
+ free(ppd->attrs);
}
cupsArrayDelete(ppd->sorted_attrs);
case PPD_CUSTOM_PASSCODE :
case PPD_CUSTOM_PASSWORD :
case PPD_CUSTOM_STRING :
- _cupsStrFree(cparam->current.custom_string);
+ free(cparam->current.custom_string);
break;
default :
* Free the whole record...
*/
- ppd_free(ppd);
+ free(ppd);
}
if (pg->ppd_status == PPD_OK)
pg->ppd_status = PPD_MISSING_PPDADOBE4;
- _cupsStrFree(string);
- ppd_free(line.buffer);
+ free(string);
+ free(line.buffer);
return (NULL);
}
DEBUG_printf(("2_ppdOpen: keyword=%s, string=%p", keyword, string));
- _cupsStrFree(string);
-
/*
* Allocate memory for the PPD file record...
*/
{
pg->ppd_status = PPD_ALLOC_ERROR;
- _cupsStrFree(string);
- ppd_free(line.buffer);
+ free(string);
+ free(line.buffer);
return (NULL);
}
+ free(string);
+ string = NULL;
+
ppd->language_level = 2;
ppd->color_device = 0;
ppd->colorspace = PPD_CS_N;
ppd->landscape = -90;
- ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions,
- NULL);
+ ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions, NULL);
/*
* Read lines from the PPD file and add them to the file record...
strncmp(ll, keyword, ll_len)))
{
DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword));
+ free(string);
+ string = NULL;
continue;
}
else if (localization == _PPD_LOCALIZATION_ICC_PROFILES)
if (i >= (int)(sizeof(color_keywords) / sizeof(color_keywords[0])))
{
DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword));
+ free(string);
+ string = NULL;
continue;
}
}
* Say all PPD files are UTF-8, since we convert to UTF-8...
*/
- ppd->lang_encoding = _cupsStrAlloc("UTF-8");
+ ppd->lang_encoding = strdup("UTF-8");
encoding = _ppdGetEncoding(string);
}
else if (!strcmp(keyword, "LanguageVersion"))
cupsCharsetToUTF8(utf8, string, sizeof(utf8), encoding);
- ppd->nickname = _cupsStrAlloc((char *)utf8);
+ ppd->nickname = strdup((char *)utf8);
}
else
- ppd->nickname = _cupsStrAlloc(string);
+ ppd->nickname = strdup(string);
}
else if (!strcmp(keyword, "Product"))
ppd->product = string;
ppd->ttrasterizer = string;
else if (!strcmp(keyword, "JCLBegin"))
{
- ppd->jcl_begin = _cupsStrAlloc(string);
+ ppd->jcl_begin = strdup(string);
ppd_decode(ppd->jcl_begin); /* Decode quoted string */
}
else if (!strcmp(keyword, "JCLEnd"))
{
- ppd->jcl_end = _cupsStrAlloc(string);
+ ppd->jcl_end = strdup(string);
ppd_decode(ppd->jcl_end); /* Decode quoted string */
}
else if (!strcmp(keyword, "JCLToPSInterpreter"))
{
- ppd->jcl_ps = _cupsStrAlloc(string);
+ ppd->jcl_ps = strdup(string);
ppd_decode(ppd->jcl_ps); /* Decode quoted string */
}
else if (!strcmp(keyword, "AccurateScreensSupport"))
- ppd->accurate_screens = !strcmp(string, "True");
+ ppd->accurate_screens = !strcasecmp(string, "True");
else if (!strcmp(keyword, "ColorDevice"))
- ppd->color_device = !strcmp(string, "True");
+ ppd->color_device = !strcasecmp(string, "True");
else if (!strcmp(keyword, "ContoneOnly"))
- ppd->contone_only = !strcmp(string, "True");
+ ppd->contone_only = !strcasecmp(string, "True");
else if (!strcmp(keyword, "cupsFlipDuplex"))
- ppd->flip_duplex = !strcmp(string, "True");
+ ppd->flip_duplex = !strcasecmp(string, "True");
else if (!strcmp(keyword, "cupsManualCopies"))
- ppd->manual_copies = !strcmp(string, "True");
+ ppd->manual_copies = !strcasecmp(string, "True");
else if (!strcmp(keyword, "cupsModelNumber"))
ppd->model_number = atoi(string);
else if (!strcmp(keyword, "cupsColorProfile"))
ppd->num_filters ++;
/*
- * Retain a copy of the filter string...
+ * Make a copy of the filter string...
*/
- *filter = _cupsStrRetain(string);
+ *filter = strdup(string);
}
else if (!strcmp(keyword, "Throughput"))
ppd->throughput = atoi(string);
}
ppd->fonts = tempfonts;
- ppd->fonts[ppd->num_fonts] = _cupsStrAlloc(name);
+ ppd->fonts[ppd->num_fonts] = strdup(name);
ppd->num_fonts ++;
}
else if (!strncmp(keyword, "ParamCustom", 11))
goto error;
}
+ if (cparam->type != PPD_CUSTOM_UNKNOWN)
+ {
+ pg->ppd_status = PPD_BAD_CUSTOM_PARAM;
+
+ goto error;
+ }
+
/*
* Get the parameter data...
*/
strlcpy(choice->text, text[0] ? text : _("Custom"),
sizeof(choice->text));
- choice->code = _cupsStrAlloc(string);
+ choice->code = strdup(string);
if (custom_option->section == PPD_ORDER_JCL)
ppd_decode(choice->code);
else if (!strcmp(string, "Plus90"))
ppd->landscape = 90;
}
+ else if (!strcmp(keyword, "Emulators") && string && ppd->num_emulations == 0)
+ {
+ /*
+ * Issue #5562: Samsung printer drivers incorrectly use Emulators keyword
+ * to configure themselves
+ *
+ * The Emulators keyword was loaded but never used by anything in CUPS,
+ * and has no valid purpose in CUPS. The old code was removed due to a
+ * memory leak (Issue #5475), so the following (new) code supports a single
+ * name for the Emulators keyword, allowing these drivers to work until we
+ * remove PPD and driver support entirely in a future version of CUPS.
+ */
+
+ ppd->num_emulations = 1;
+ ppd->emulations = calloc(1, sizeof(ppd_emul_t));
+
+ strlcpy(ppd->emulations[0].name, string, sizeof(ppd->emulations[0].name));
+ }
else if (!strcmp(keyword, "JobPatchFile"))
{
/*
option->section = PPD_ORDER_ANY;
- _cupsStrFree(string);
+ free(string);
string = NULL;
/*
strlcpy(choice->text,
custom_attr->text[0] ? custom_attr->text : _("Custom"),
sizeof(choice->text));
- choice->code = _cupsStrRetain(custom_attr->value);
+ choice->code = strdup(custom_attr->value);
}
}
else if (!strcmp(keyword, "JCLOpenUI"))
option->section = PPD_ORDER_JCL;
group = NULL;
- _cupsStrFree(string);
+ free(string);
string = NULL;
/*
strlcpy(choice->text,
custom_attr->text[0] ? custom_attr->text : _("Custom"),
sizeof(choice->text));
- choice->code = _cupsStrRetain(custom_attr->value);
+ choice->code = strdup(custom_attr->value);
}
}
else if (!strcmp(keyword, "CloseUI"))
goto error;
}
+ if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
+ {
+ /*
+ * "*DefaultOption: Custom..." may set the default to a custom value
+ * or (for a very small number of incompatible PPD files) select a
+ * standard choice for the option, which CUPS renames to "_Custom..."
+ * to avoid compatibility issues. See which this is...
+ */
+
+ char tchoice[PPD_MAX_NAME]; /* Temporary choice name */
+
+ snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
+
+ if (ppdFindChoice(option, tchoice))
+ {
+ strlcpy(option->defchoice, tchoice, sizeof(option->defchoice));
+
+ DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice));
+ }
+ }
+
option = NULL;
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "JCLCloseUI"))
goto error;
}
+ if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
+ {
+ /*
+ * "*DefaultOption: Custom..." may set the default to a custom value
+ * or (for a very small number of incompatible PPD files) select a
+ * standard choice for the option, which CUPS renames to "_Custom..."
+ * to avoid compatibility issues. See which this is...
+ */
+
+ char tchoice[PPD_MAX_NAME]; /* Temporary choice name */
+
+ snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
+
+ if (ppdFindChoice(option, tchoice))
+ {
+ strlcpy(option->defchoice, tchoice, sizeof(option->defchoice));
+
+ DEBUG_printf(("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice));
+ }
+ }
+
option = NULL;
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "OpenGroup"))
if (group == NULL)
goto error;
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "CloseGroup"))
{
group = NULL;
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "OrderDependency"))
option->order = order;
}
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strncmp(keyword, "Default", 7))
* Set the default as part of the current option...
*/
- DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string));
-
- strlcpy(option->defchoice, string, sizeof(option->defchoice));
+ strlcpy(option->defchoice, string, sizeof(option->defchoice));
- DEBUG_printf(("2_ppdOpen: %s is now %s...", keyword, option->defchoice));
+ DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, option->defchoice));
}
else
{
ppd_option_t *toption; /* Temporary option */
-
if ((toption = ppdFindOption(ppd, keyword + 7)) != NULL)
{
- DEBUG_printf(("2_ppdOpen: Setting %s to %s...", keyword, string));
- strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+ if (!_cups_strcasecmp(string, "custom") || !_cups_strncasecmp(string, "custom.", 7))
+ {
+ /*
+ * "*DefaultOption: Custom..." may set the default to a custom value
+ * or (for a very small number of incompatible PPD files) select a
+ * standard choice for the option, which CUPS renames to "_Custom..."
+ * to avoid compatibility issues. See which this is...
+ */
+
+ snprintf(toption->defchoice, sizeof(toption->defchoice), "_%s", string);
+ if (!ppdFindChoice(toption, toption->defchoice))
+ strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+ }
+ else
+ {
+ strlcpy(toption->defchoice, string, sizeof(toption->defchoice));
+ }
+
+ DEBUG_printf(("2_ppdOpen: Set %s to %s...", keyword, toption->defchoice));
}
}
}
constraint->choice1, constraint->option2,
constraint->choice2))
{
- case 0 : /* Error */
- case 1 : /* Error */
+ default : /* Error */
pg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
goto error;
* Don't add this one as an attribute...
*/
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "PaperDimension"))
{
+ if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+ {
+ char cname[PPD_MAX_NAME]; /* Rewrite with a leading underscore */
+ snprintf(cname, sizeof(cname), "_%s", name);
+ strlcpy(name, cname, sizeof(name));
+ }
+
if ((size = ppdPageSize(ppd, name)) == NULL)
size = ppd_add_size(ppd, name);
size->width = (float)_cupsStrScand(string, &sptr, loc);
size->length = (float)_cupsStrScand(sptr, NULL, loc);
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (!strcmp(keyword, "ImageableArea"))
{
+ if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+ {
+ char cname[PPD_MAX_NAME]; /* Rewrite with a leading underscore */
+ snprintf(cname, sizeof(cname), "_%s", name);
+ strlcpy(name, cname, sizeof(name));
+ }
+
if ((size = ppdPageSize(ppd, name)) == NULL)
size = ppd_add_size(ppd, name);
size->right = (float)_cupsStrScand(sptr, &sptr, loc);
size->top = (float)_cupsStrScand(sptr, NULL, loc);
- _cupsStrFree(string);
+ free(string);
string = NULL;
}
else if (option != NULL &&
{
DEBUG_printf(("2_ppdOpen: group=%p, subgroup=%p", group, subgroup));
+ if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7))
+ {
+ char cname[PPD_MAX_NAME]; /* Rewrite with a leading underscore */
+ snprintf(cname, sizeof(cname), "_%s", name);
+ strlcpy(name, cname, sizeof(name));
+ }
+
if (!strcmp(keyword, "PageSize"))
{
/*
(mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING))
ppd_add_attr(ppd, keyword, name, text, string);
else
- _cupsStrFree(string);
+ free(string);
}
/*
goto error;
}
- ppd_free(line.buffer);
+ free(line.buffer);
/*
* Reset language preferences...
error:
- _cupsStrFree(string);
- ppd_free(line.buffer);
+ free(string);
+ free(line.buffer);
ppdClose(ppd);
* Copy data over...
*/
+ if (!_cups_strcasecmp(spec, "custom") || !_cups_strncasecmp(spec, "custom.", 7))
+ {
+ temp->spec[0] = '_';
+ strlcpy(temp->spec + 1, spec, sizeof(temp->spec) - 1);
+ }
+ else {
+ strlcpy(temp->spec, spec, sizeof(temp->spec));
+ }
+
strlcpy(temp->name, name, sizeof(temp->name));
- strlcpy(temp->spec, spec, sizeof(temp->spec));
strlcpy(temp->text, text, sizeof(temp->text));
temp->value = (char *)value;
if (ppd->num_filters > 0)
{
for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++)
- _cupsStrFree(*filter);
+ free(*filter);
- ppd_free(ppd->filters);
+ free(ppd->filters);
ppd->num_filters = 0;
ppd->filters = NULL;
i --, option ++)
ppd_free_option(option);
- ppd_free(group->options);
+ free(group->options);
}
if (group->num_subgroups > 0)
i --, subgroup ++)
ppd_free_group(subgroup);
- ppd_free(group->subgroups);
+ free(group->subgroups);
}
}
i > 0;
i --, choice ++)
{
- _cupsStrFree(choice->code);
+ free(choice->code);
}
- ppd_free(option->choices);
+ free(option->choices);
}
}
if ((cparam = calloc(1, sizeof(ppd_cparam_t))) == NULL)
return (NULL);
+ cparam->type = PPD_CUSTOM_UNKNOWN;
strlcpy(cparam->name, param, sizeof(cparam->name));
strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text));
for (hash = option->keyword[0], k = option->keyword + 1; *k;)
- hash = 33 * hash + *k++;
+ hash = (int)(33U * (unsigned)hash) + *k++;
return (hash & 511);
}
lineptr ++;
}
- *string = _cupsStrAlloc(lineptr);
+ *string = strdup(lineptr);
mask |= PPD_STRING;
}
filter += ppd->num_filters;
ppd->num_filters ++;
- *filter = _cupsStrAlloc(buffer);
+ *filter = strdup(buffer);
}
while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL);