From 391e008f89267da6666ec0f63c72be8883e4af76 Mon Sep 17 00:00:00 2001 From: Dhirender Choudhary Date: Sun, 8 Nov 2026 23:23:27 +0530 Subject: [PATCH 1/2] Test that a preset newline cannot start a PPD directive. --- ppd/test_ppd_generator.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ppd/test_ppd_generator.c b/ppd/test_ppd_generator.c index 6bd95885..949f80bf 100644 --- a/ppd/test_ppd_generator.c +++ b/ppd/test_ppd_generator.c @@ -1159,6 +1159,42 @@ main(void) "status=\"%s\"", status_msg); ippDelete(resp); + // T46 — Unknown job-presets-supported text is copied with + // ippAttributeString, which keeps embedded newlines. A newline + // starts a new PPD statement. A known member (sides) and a + // keyword member (print-color-mode) must still be written. + testBegin("preset text newline is not a new PPD directive"); + resp = make_pdf_ipp(); + { + ipp_t *preset = ippNew(); + + ippAddString(preset, IPP_TAG_ZERO, IPP_TAG_NAME, "preset-name", + NULL, "Office"); + ippAddString(preset, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "sides", + NULL, "one-sided"); + ippAddString(preset, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "print-color-mode", + NULL, "monochrome"); + ippAddString(preset, IPP_TAG_ZERO, IPP_TAG_TEXT, "evil-option", NULL, + "ok\n*INJECTED-DIRECTIVE evil"); + ippAddCollection(resp, IPP_TAG_PRINTER, "job-presets-supported", preset); + ippDelete(preset); + } + result = ppdCreatePPDFromIPP2(buffer, sizeof(buffer), resp, + "Test", "application/pdf", + 0, 0, NULL, NULL, NULL, NULL, NULL, 0); + ppd_text = result ? slurp_file(buffer) : NULL; + testEndMessage(ppd_text && + strstr(ppd_text, "*Duplex None\n") && + strstr(ppd_text, "*print-color-mode monochrome\n") && + strstr(ppd_text, "INJECTED-DIRECTIVE") == NULL, + "duplex=%d color=%d injected=%d", + ppd_text && strstr(ppd_text, "*Duplex None\n") != NULL, + ppd_text && strstr(ppd_text, "*print-color-mode monochrome\n") != NULL, + ppd_text && strstr(ppd_text, "INJECTED-DIRECTIVE") != NULL); + if (result == buffer) unlink(buffer); + free(ppd_text); + ippDelete(resp); + return (testsPassed ? 0 : 1); } From 30448f850fdb7aafbe43117d2a2e749bedbfd5f7 Mon Sep 17 00:00:00 2001 From: Dhirender Choudhary Date: Sun, 8 Nov 2026 23:24:39 +0530 Subject: [PATCH 2/2] ppd-generator.c: Copy only scalar preset members into the PPD. --- ppd/ppd-generator.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ppd/ppd-generator.c b/ppd/ppd-generator.c index 081e84aa..3e288d6f 100644 --- a/ppd/ppd-generator.c +++ b/ppd/ppd-generator.c @@ -2847,12 +2847,15 @@ ppdCreatePPDFromIPP2(char *buffer, // I - Filename buffer else if (keyword && !strcmp(keyword, "two-sided-short-edge")) cupsFilePuts(fp, "*Duplex DuplexTumble\n"); } - else + else if ((ippGetValueTag(member) == IPP_TAG_BOOLEAN || + ippGetValueTag(member) == IPP_TAG_INTEGER || + ippGetValueTag(member) == IPP_TAG_KEYWORD) && + ippValidateAttribute(member)) { - // - // Add attribute name and value as-is... - // - + // Text and name values may contain newlines. A newline here + // starts a new PPD statement. Boolean, integer, and keyword + // values are single tokens, and ippValidateAttribute rejects + // a member name that is not a keyword. ippAttributeString(member, member_value, sizeof(member_value)); cupsFilePrintf(fp, "*%s %s\n", member_name, member_value); }