X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fcups.git;a=blobdiff_plain;f=cups%2Fppd.c;h=ac5dbc62bb8d78aa8de022f8f9bb854d4525eaa8;hp=21443e6b02d3c204ae2544e5dbb07fb02d90e76d;hb=HEAD;hpb=f787e1e3ff11339269bdc11e253af91e5961e013 diff --git a/cups/ppd.c b/cups/ppd.c index 21443e6b0..ac5dbc62b 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,27 +1,13 @@ /* - * "$Id$" - * * PPD file routines for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -30,14 +16,13 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* * 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 */ @@ -96,9 +81,9 @@ static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name, cups_encoding_t encoding); static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name); static _ppd_globals_t *ppd_globals_alloc(void); -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void ppd_globals_free(_ppd_globals_t *g); -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H static void ppd_globals_init(void); #endif /* HAVE_PTHREAD_H */ @@ -119,7 +104,6 @@ void ppdClose(ppd_file_t *ppd) /* I - PPD file record */ { int i; /* Looping var */ - ppd_emul_t *emul; /* Current emulation */ ppd_group_t *group; /* Current group */ char **font; /* Current font */ ppd_attr_t **attr; /* Current attribute */ @@ -138,28 +122,13 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ * 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 any emulations... - */ - - if (ppd->num_emulations > 0) - { - for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++) - { - _cupsStrFree(emul->start); - _cupsStrFree(emul->stop); - } - - ppd_free(ppd->emulations); - } + 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... @@ -170,7 +139,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ 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); @@ -181,14 +150,14 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ */ 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... @@ -203,9 +172,9 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ 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); } /* @@ -213,7 +182,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ */ if (ppd->num_profiles > 0) - ppd_free(ppd->profiles); + free(ppd->profiles); /* * Free any attributes... @@ -223,11 +192,11 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ { 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); @@ -249,7 +218,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ case PPD_CUSTOM_PASSCODE : case PPD_CUSTOM_PASSWORD : case PPD_CUSTOM_STRING : - _cupsStrFree(cparam->current.custom_string); + free(cparam->current.custom_string); break; default : @@ -297,14 +266,14 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ * Free the whole record... */ - ppd_free(ppd); + free(ppd); } /* * 'ppdErrorString()' - Returns the text associated with a status. * - * @since CUPS 1.1.19/OS X 10.3@ + * @since CUPS 1.1.19/macOS 10.3@ */ const char * /* O - Status string */ @@ -335,7 +304,9 @@ ppdErrorString(ppd_status_t status) /* I - PPD status */ _("Bad custom parameter"), _("Missing option keyword"), _("Bad value string"), - _("Missing CloseGroup") + _("Missing CloseGroup"), + _("Bad CloseUI/JCLCloseUI"), + _("Missing CloseUI/JCLCloseUI") }; @@ -414,7 +385,7 @@ _ppdGlobals(void) /* * 'ppdLastError()' - Return the status from the last ppdOpen*(). * - * @since CUPS 1.1.19/OS X 10.3@ + * @since CUPS 1.1.19/macOS 10.3@ */ ppd_status_t /* O - Status code */ @@ -434,7 +405,7 @@ ppdLastError(int *line) /* O - Line number */ /* * '_ppdOpen()' - Read a PPD file into memory. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */ @@ -443,7 +414,6 @@ _ppdOpen( _ppd_localization_t localization) /* I - Localization to load */ { int i, j, k; /* Looping vars */ - int count; /* Temporary count */ _ppd_line_t line; /* Line buffer */ ppd_file_t *ppd; /* PPD file record */ ppd_group_t *group, /* Current group */ @@ -461,7 +431,6 @@ _ppdOpen( /* Human-readable text from file */ *string, /* Code/text from file */ *sptr, /* Pointer into string */ - *nameptr, /* Pointer into name */ *temp, /* Temporary string pointer */ **tempfonts; /* Temporary fonts pointer */ float order; /* Order dependency number */ @@ -581,12 +550,28 @@ _ppdOpen( /* * + * * * Need to use a different base language for some locales... */ if (!strcmp(lang->language, "zh_HK")) - strlcpy(ll, "zh_TW.", sizeof(ll)); + { /* Traditional Chinese + variants */ + strlcpy(ll_CC, "zh_TW.", sizeof(ll_CC)); + strlcpy(ll, "zh_", sizeof(ll)); + } + else if (!strncmp(lang->language, "zh", 2)) + strlcpy(ll, "zh_", sizeof(ll)); /* Any Chinese variant */ + else if (!strncmp(lang->language, "jp", 2)) + { /* Any Japanese variant */ + strlcpy(ll_CC, "ja", sizeof(ll_CC)); + strlcpy(ll, "jp", sizeof(ll)); + } + else if (!strncmp(lang->language, "nb", 2) || !strncmp(lang->language, "no", 2)) + { /* Any Norwegian variant */ + strlcpy(ll_CC, "nb", sizeof(ll_CC)); + strlcpy(ll, "no", sizeof(ll)); + } else snprintf(ll, sizeof(ll), "%2.2s.", lang->language); @@ -619,16 +604,14 @@ _ppdOpen( 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... */ @@ -637,18 +620,20 @@ _ppdOpen( { 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... @@ -721,6 +706,8 @@ _ppdOpen( 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) @@ -740,6 +727,8 @@ _ppdOpen( if (i >= (int)(sizeof(color_keywords) / sizeof(color_keywords[0]))) { DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword)); + free(string); + string = NULL; continue; } } @@ -835,7 +824,7 @@ _ppdOpen( * 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")) @@ -856,10 +845,10 @@ _ppdOpen( 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; @@ -869,29 +858,29 @@ _ppdOpen( 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")) @@ -947,10 +936,10 @@ _ppdOpen( 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); @@ -973,7 +962,7 @@ _ppdOpen( } 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)) @@ -1004,6 +993,13 @@ _ppdOpen( goto error; } + if (cparam->type != PPD_CUSTOM_UNKNOWN) + { + pg->ppd_status = PPD_BAD_CUSTOM_PARAM; + + goto error; + } + /* * Get the parameter data... */ @@ -1138,7 +1134,7 @@ _ppdOpen( 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); @@ -1187,59 +1183,23 @@ _ppdOpen( else if (!strcmp(string, "Plus90")) ppd->landscape = 90; } - else if (!strcmp(keyword, "Emulators") && string) + else if (!strcmp(keyword, "Emulators") && string && ppd->num_emulations == 0) { - for (count = 1, sptr = string; sptr != NULL;) - if ((sptr = strchr(sptr, ' ')) != NULL) - { - count ++; - while (*sptr == ' ') - sptr ++; - } - - ppd->num_emulations = count; - if ((ppd->emulations = calloc((size_t)count, sizeof(ppd_emul_t))) == NULL) - { - pg->ppd_status = PPD_ALLOC_ERROR; - - goto error; - } - - for (i = 0, sptr = string; i < count; i ++) - { - for (nameptr = ppd->emulations[i].name; - *sptr != '\0' && *sptr != ' '; - sptr ++) - if (nameptr < (ppd->emulations[i].name + sizeof(ppd->emulations[i].name) - 1)) - *nameptr++ = *sptr; - - *nameptr = '\0'; - - while (*sptr == ' ') - sptr ++; - } - } - else if (!strncmp(keyword, "StartEmulator_", 14)) - { - ppd_decode(string); + /* + * 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. + */ - for (i = 0; i < ppd->num_emulations; i ++) - if (!strcmp(keyword + 14, ppd->emulations[i].name)) - { - ppd->emulations[i].start = string; - string = NULL; - } - } - else if (!strncmp(keyword, "StopEmulator_", 13)) - { - ppd_decode(string); + ppd->num_emulations = 1; + ppd->emulations = calloc(1, sizeof(ppd_emul_t)); - for (i = 0; i < ppd->num_emulations; i ++) - if (!strcmp(keyword + 13, ppd->emulations[i].name)) - { - ppd->emulations[i].stop = string; - string = NULL; - } + strlcpy(ppd->emulations[0].name, string, sizeof(ppd->emulations[0].name)); } else if (!strcmp(keyword, "JobPatchFile")) { @@ -1394,7 +1354,7 @@ _ppdOpen( option->section = PPD_ORDER_ANY; - _cupsStrFree(string); + free(string); string = NULL; /* @@ -1422,7 +1382,7 @@ _ppdOpen( 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")) @@ -1501,7 +1461,7 @@ _ppdOpen( option->section = PPD_ORDER_JCL; group = NULL; - _cupsStrFree(string); + free(string); string = NULL; /* @@ -1525,14 +1485,77 @@ _ppdOpen( 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") || !strcmp(keyword, "JCLCloseUI")) + else if (!strcmp(keyword, "CloseUI")) { + if ((!option || option->section == PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_BAD_CLOSE_UI; + + 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; + + free(string); + string = NULL; + } + else if (!strcmp(keyword, "JCLCloseUI")) + { + if ((!option || option->section != PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_BAD_CLOSE_UI; + + 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")) @@ -1579,14 +1602,14 @@ _ppdOpen( 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")) @@ -1644,7 +1667,7 @@ _ppdOpen( option->order = order; } - _cupsStrFree(string); + free(string); string = NULL; } else if (!strncmp(keyword, "Default", 7)) @@ -1688,11 +1711,9 @@ _ppdOpen( * 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 { @@ -1702,11 +1723,27 @@ _ppdOpen( 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)); } } } @@ -1739,8 +1776,7 @@ _ppdOpen( constraint->choice1, constraint->option2, constraint->choice2)) { - case 0 : /* Error */ - case 1 : /* Error */ + default : /* Error */ pg->ppd_status = PPD_BAD_UI_CONSTRAINTS; goto error; @@ -1887,11 +1923,18 @@ _ppdOpen( * 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); @@ -1909,11 +1952,18 @@ _ppdOpen( 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); @@ -1933,7 +1983,7 @@ _ppdOpen( size->right = (float)_cupsStrScand(sptr, &sptr, loc); size->top = (float)_cupsStrScand(sptr, NULL, loc); - _cupsStrFree(string); + free(string); string = NULL; } else if (option != NULL && @@ -1943,6 +1993,13 @@ _ppdOpen( { 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")) { /* @@ -1989,7 +2046,17 @@ _ppdOpen( (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING)) ppd_add_attr(ppd, keyword, name, text, string); else - _cupsStrFree(string); + free(string); + } + + /* + * Check for a missing CloseUI/JCLCloseUI... + */ + + if (option && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_MISSING_CLOSE_UI; + goto error; } /* @@ -2002,7 +2069,7 @@ _ppdOpen( goto error; } - ppd_free(line.buffer); + free(line.buffer); /* * Reset language preferences... @@ -2084,8 +2151,8 @@ _ppdOpen( error: - _cupsStrFree(string); - ppd_free(line.buffer); + free(string); + free(line.buffer); ppdClose(ppd); @@ -2130,7 +2197,7 @@ ppdOpen(FILE *fp) /* I - File to read from */ /* * 'ppdOpen2()' - Read a PPD file into memory. * - * @since CUPS 1.2/OS X 10.5@ + * @since CUPS 1.2/macOS 10.5@ */ ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */ @@ -2255,7 +2322,7 @@ ppdOpenFile(const char *filename) /* I - File to read from */ /* * 'ppdSetConformance()' - Set the conformance level for PPD files. * - * @since CUPS 1.1.20/OS X 10.4@ + * @since CUPS 1.1.20/macOS 10.4@ */ void @@ -2325,8 +2392,16 @@ ppd_add_attr(ppd_file_t *ppd, /* I - PPD file data */ * 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; @@ -2523,9 +2598,9 @@ ppd_free_filters(ppd_file_t *ppd) /* I - PPD file */ 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; @@ -2552,7 +2627,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ i --, option ++) ppd_free_option(option); - ppd_free(group->options); + free(group->options); } if (group->num_subgroups > 0) @@ -2562,7 +2637,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ i --, subgroup ++) ppd_free_group(subgroup); - ppd_free(group->subgroups); + free(group->subgroups); } } @@ -2584,10 +2659,10 @@ ppd_free_option(ppd_option_t *option) /* I - Option to free */ i > 0; i --, choice ++) { - _cupsStrFree(choice->code); + free(choice->code); } - ppd_free(option->choices); + free(option->choices); } } @@ -2657,6 +2732,7 @@ ppd_get_cparam(ppd_coption_t *opt, /* I - PPD file */ 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)); @@ -2790,13 +2866,13 @@ ppd_globals_alloc(void) * 'ppd_globals_free()' - Free global data. */ -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void ppd_globals_free(_ppd_globals_t *pg) /* I - Pointer to global data */ { free(pg); } -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H @@ -2828,7 +2904,7 @@ ppd_hash_option(ppd_option_t *option) /* I - Option */ for (hash = option->keyword[0], k = option->keyword + 1; *k;) - hash = 33 * hash + *k++; + hash = (int)(33U * (unsigned)hash) + *k++; return (hash & 511); } @@ -3124,7 +3200,7 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ DEBUG_printf(("9ppd_read: LINE=\"%s\"", line->buffer)); /* - * The dynamically created PPDs for older style OS X + * The dynamically created PPDs for older style macOS * drivers include a large blob of data inserted as comments * at the end of the file. As an optimization we can stop * reading the PPD when we get to the start of this data. @@ -3324,7 +3400,7 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ lineptr ++; } - *string = _cupsStrAlloc(lineptr); + *string = strdup(lineptr); mask |= PPD_STRING; } @@ -3446,15 +3522,10 @@ ppd_update_filters(ppd_file_t *ppd, /* I - PPD file */ filter += ppd->num_filters; ppd->num_filters ++; - *filter = _cupsStrAlloc(buffer); + *filter = strdup(buffer); } while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); DEBUG_puts("5ppd_update_filters: Completed OK."); return (1); } - - -/* - * End of "$Id$". - */