From c5b7e31c14f3ec8f2433b997e4f4e739e062eb91 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 11 Mar 2025 07:08:38 +0000 Subject: [PATCH] import CS cups-filters-1.28.7-20.el9 --- ...enerate-PPD-for-remote-raw-queues-44.patch | 51 ++ ...ibutes5-Validate-response-attributes.patch | 19 + ...n-pdftopdf-fix-cropping-with-long-ed.patch | 36 ++ ...olerance-for-input-size-larger-than-.patch | 39 ++ ...rint-scaling-and-N-up-for-asymmetric.patch | 480 ++++++++++++++++++ ...opdf-Set-a-default-for-print-scaling.patch | 36 ++ SOURCES/browsed-ignore-NULL-attrs.patch | 31 ++ SOURCES/cups-filters-CVE-2024-47175.patch | 376 ++++++++++++++ SPECS/cups-filters.spec | 79 ++- 9 files changed, 1145 insertions(+), 2 deletions(-) create mode 100644 SOURCES/0001-Do-not-generate-PPD-for-remote-raw-queues-44.patch create mode 100644 SOURCES/0001-cfGetPrinterAttributes5-Validate-response-attributes.patch create mode 100644 SOURCES/0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch create mode 100644 SOURCES/0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch create mode 100644 SOURCES/0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patch create mode 100644 SOURCES/0001-pdftopdf-Set-a-default-for-print-scaling.patch create mode 100644 SOURCES/browsed-ignore-NULL-attrs.patch create mode 100644 SOURCES/cups-filters-CVE-2024-47175.patch diff --git a/SOURCES/0001-Do-not-generate-PPD-for-remote-raw-queues-44.patch b/SOURCES/0001-Do-not-generate-PPD-for-remote-raw-queues-44.patch new file mode 100644 index 0000000..76476e9 --- /dev/null +++ b/SOURCES/0001-Do-not-generate-PPD-for-remote-raw-queues-44.patch @@ -0,0 +1,51 @@ +diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c +index a5e5779..b190829 100644 +--- a/utils/cups-browsed.c ++++ b/utils/cups-browsed.c +@@ -7271,8 +7271,14 @@ create_remote_printer_entry (const char *queue_name, + p->prattrs = get_printer_attributes(p->uri, NULL, 0, NULL, 0, 1); + debug_log_out(get_printer_attributes_log); + if (p->prattrs == NULL) ++ { + debug_printf("get-printer-attributes IPP call failed on printer %s (%s).\n", + p->queue_name, p->uri); ++ goto fail; ++ } ++ ++ attr = ippFindAttribute(p->prattrs, "printer-make-and-model", IPP_TAG_TEXT); ++ p->make_model = attr ? strdup(ippGetString(attr, 0, NULL)) : NULL; + } + } else { + #ifndef HAVE_CUPS_1_6 +@@ -8242,7 +8248,8 @@ gboolean update_cups_queues(gpointer unused) { + debug_printf("Generated Default Attributes for local queue %s\n", + p->queue_name); + } +- if (ppdfile == NULL) { ++ if (ppdfile == NULL && make_model && strcmp(make_model, "Local Raw Printer")) ++ { + /* If we do not want CUPS-generated PPDs or we cannot obtain a + CUPS-generated PPD, for example if CUPS does not create a + temporary queue for this printer, we generate a PPD by +@@ -8580,7 +8587,8 @@ gboolean update_cups_queues(gpointer unused) { + debug_printf("Generated Default Attributes for local queue %s\n", + p->queue_name); + } +- if (ppdfile == NULL) { ++ if (ppdfile == NULL && make_model && strcmp(make_model, "Local Raw Printer")) ++ { + /* If we do not want CUPS-generated PPDs or we cannot obtain a + CUPS-generated PPD, for example if CUPS does not create a + temporary queue for this printer, we generate a PPD by +@@ -8793,6 +8801,11 @@ gboolean update_cups_queues(gpointer unused) { + } + ppdfile = strdup(buf); + } ++ else ++ { ++ // No PPD - define nickname as make_model for remote raw queue ++ p->nickname = p->make_model ? strdup(p->make_model) : strdup("Local Raw Printer"); ++ } + + /* Create a new CUPS queue or modify the existing queue */ + request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); diff --git a/SOURCES/0001-cfGetPrinterAttributes5-Validate-response-attributes.patch b/SOURCES/0001-cfGetPrinterAttributes5-Validate-response-attributes.patch new file mode 100644 index 0000000..fde51bd --- /dev/null +++ b/SOURCES/0001-cfGetPrinterAttributes5-Validate-response-attributes.patch @@ -0,0 +1,19 @@ +diff --git a/cupsfilters/ipp.c b/cupsfilters/ipp.c +index 2c3b740..6b2b784 100644 +--- a/cupsfilters/ipp.c ++++ b/cupsfilters/ipp.c +@@ -377,6 +377,14 @@ get_printer_attributes5(http_t *http_printer, + total_attrs); + ippDelete(response); + } else { ++ ++ // Check if the response is valid ++ if (!ippValidateAttributes(response)) ++ { ++ ippDelete(response); ++ response = NULL; ++ } ++ + /* Suitable response, we are done */ + if (have_http == 0) httpClose(http_printer); + if (uri) free(uri); diff --git a/SOURCES/0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch b/SOURCES/0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch new file mode 100644 index 0000000..190e198 --- /dev/null +++ b/SOURCES/0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch @@ -0,0 +1,36 @@ +From d4ae67231047ac6a4d532d96ddf2234465d57c1d Mon Sep 17 00:00:00 2001 +From: Till Kamppeter +Date: Sun, 27 Mar 2022 17:51:12 +0200 +Subject: [PATCH] libcupsfilters: In pdftopdf() fix cropping with + long-edge-first + +If the printer takes the paper long-edge-first (lasers and inkjets +usually take it short-edge first, but roll-fed large-formats or label +printers also take long-edge-first) the cropping of the page image for +crop-to-fit (print-scaling=none) and fill (print-scaling=fill) by the +pdftopdf() filter function did not work correctly. This is fixed now. + +Issue #454 + +(manually backported from commit 70e0f47082550ae212f6b2741a447cbae17a857d) +--- + filter/pdftopdf/qpdf_pdftopdf_processor.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/filter/pdftopdf/qpdf_pdftopdf_processor.cc b/filter/pdftopdf/qpdf_pdftopdf_processor.cc +index 621c76880..a330e825f 100644 +--- a/filter/pdftopdf/qpdf_pdftopdf_processor.cc ++++ b/filter/pdftopdf/qpdf_pdftopdf_processor.cc +@@ -193,7 +193,8 @@ Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orient + double final_w,final_h; //Width and height of cropped image. + + Rotation pageRot = getRotate(page); +- if(pageRot==ROT_0||pageRot==ROT_180) ++ if (((pageRot == ROT_0 || pageRot == ROT_180) && pageWidth <= pageHeight) || ++ ((pageRot == ROT_90 || pageRot == ROT_270) && pageWidth > pageHeight)) + { + std::swap(pageHeight,pageWidth); + } +-- +2.47.1 + diff --git a/SOURCES/0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch b/SOURCES/0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch new file mode 100644 index 0000000..b8035f1 --- /dev/null +++ b/SOURCES/0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch @@ -0,0 +1,39 @@ +From ddd9da98fd86be3730747f1da921b22f2452062c Mon Sep 17 00:00:00 2001 +From: Till Kamppeter +Date: Sat, 5 Feb 2022 16:22:10 -0300 +Subject: [PATCH] pdftopdf: Add 2% tolerance for input size larger than output + page + +When "print-scaling=auto" or "print-scaling=auto-fit" is used, the +input pages are scaled when they do not fit into the output page +size. Often input ad out page sizes are supposed to be equal, for +example both A4, but rounding errors could make the input considered +larger and unnecessarily scaled. + +Therefore we add 2% of tolerance before considering an input page too +large. + +(manually backported commit e541dc698f38aaa522f99e23b57c695da2981c29) +--- + NEWS | 6 ++++++ + filter/pdftopdf/pdftopdf_processor.cc | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/filter/pdftopdf/pdftopdf_processor.cc b/filter/pdftopdf/pdftopdf_processor.cc +index e297a246e..28643163f 100644 +--- a/filter/pdftopdf/pdftopdf_processor.cc ++++ b/filter/pdftopdf/pdftopdf_processor.cc +@@ -195,8 +195,8 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters ¶m) // {{ + for (int i = 0; i < (int)pages.size(); i ++) + { + PageRect r = pages[i]->getRect(); +- int w = r.width; +- int h = r.height; ++ int w = r.width * 100 / 102; // 2% of tolerance ++ int h = r.height * 100 / 102; + if ((w > param.page.width || h > param.page.height) && + (h > param.page.width || w > param.page.height)) + { +-- +2.47.1 + diff --git a/SOURCES/0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patch b/SOURCES/0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patch new file mode 100644 index 0000000..3de2594 --- /dev/null +++ b/SOURCES/0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patch @@ -0,0 +1,480 @@ +From 207314fc3dbcfde829f5d0082c6a23ad695d34b9 Mon Sep 17 00:00:00 2001 +From: Till Kamppeter +Date: Tue, 1 Feb 2022 23:00:46 -0300 +Subject: [PATCH] pdftopdf: Fixed print-scaling and N-up for asymmetric margins + and files with differently-sized pages + +(manually backported commit 4aaf23aae3695348532e295859f001704a33ebad + and commit 31dfcae961ca737b7166cd6a3e7d4a30cd19f9e8) +--- + NEWS | 8 + + filter/pdftopdf/pdftopdf_processor.cc | 362 ++++++++++----------- + filter/pdftopdf/qpdf_pdftopdf_processor.cc | 9 +- + 3 files changed, 189 insertions(+), 190 deletions(-) + +diff --git a/filter/pdftopdf/pdftopdf_processor.cc b/filter/pdftopdf/pdftopdf_processor.cc +index 6d2d32ff5..e297a246e 100644 +--- a/filter/pdftopdf/pdftopdf_processor.cc ++++ b/filter/pdftopdf/pdftopdf_processor.cc +@@ -175,31 +175,46 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters ¶m) // {{ + } + const int numPages=std::max(shuffle.size(),pages.size()); + ++ fprintf(stderr, "DEBUG: pdftopdf: \"print-scaling\" IPP attribute: %s\n", ++ (param.autoprint ? "auto" : ++ (param.autofit ? "auto-fit" : ++ (param.fitplot ? "fit" : ++ (param.fillprint ? "fill" : ++ (param.cropfit ? "none" : ++ "Not defined, should never happen")))))); ++ + if(param.autoprint||param.autofit){ + bool margin_defined = true; + bool document_large = false; + int pw = param.page.right-param.page.left; + int ph = param.page.top-param.page.bottom; +- int w=0,h=0; +- Rotation tempRot=param.orientation; +- PageRect r= pages[0]->getRect(); +- w = r.width; +- h = r.height; + +- if(tempRot==ROT_90||tempRot==ROT_270) ++ if ((param.page.width == pw) && (param.page.height == ph)) ++ margin_defined = false; ++ ++ for (int i = 0; i < (int)pages.size(); i ++) + { +- std::swap(w,h); ++ PageRect r = pages[i]->getRect(); ++ int w = r.width; ++ int h = r.height; ++ if ((w > param.page.width || h > param.page.height) && ++ (h > param.page.width || w > param.page.height)) ++ { ++ fprintf(stderr, ++ "DEBUG: pdftopdf: Page %d too large for output page size, scaling pages to fit.\n", ++ i + 1); ++ document_large = true; ++ } + } +- if(w>=pw||h>=ph) ++ if (param.fidelity) ++ fprintf(stderr, ++ "DEBUG: pdftopdf: \"ipp-attribute-fidelity\" IPP attribute is set, scaling pages to fit.\n"); ++ ++ if (param.autoprint) + { +- document_large = true; +- } +- if((param.page.width==pw)&& +- (param.page.height==ph)) +- margin_defined = false; +- if(param.autoprint){ +- if(param.fidelity||document_large) { +- if(margin_defined) ++ if (param.fidelity || document_large) ++ { ++ if (margin_defined) + param.fitplot = true; + else + param.fillprint = true; +@@ -215,204 +230,177 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters ¶m) // {{ + } + } + ++ fprintf(stderr, "DEBUG: pdftopdf: Print scaling mode: %s\n", ++ (param.fitplot ? ++ "Scale to fit printable area" : ++ (param.fillprint ? ++ "Scale to fill page and crop" : ++ (param.cropfit ? ++ "Do not scale, center, crop if needed" : ++ "Not defined, should never happen")))); ++ ++ // In Crop mode we do not scale the original document, it should keep the ++ // exact same size. With N-Up it should be scaled to fit exacly the halves, ++ // quarters, ... of the sheet, regardless of unprintable margins. ++ // Therefore we remove the unprintable margins to do all the math without ++ // them. ++ if (param.cropfit) ++ { ++ param.page.left = 0; ++ param.page.bottom = 0; ++ param.page.right = param.page.width; ++ param.page.top = param.page.height; ++ } ++ + if(param.fillprint||param.cropfit){ +- fprintf(stderr,"[DEBUG]: Cropping input pdf and Enabling fitplot.\n"); +- if(param.noOrientation&&pages.size()) +- { +- bool land = pages[0]->is_landscape(param.orientation); +- if(land) +- param.orientation = param.normal_landscape; +- } + for(int i=0;i<(int)pages.size();i++) + { + std::shared_ptr page = pages[i]; +- page->crop(param.page,param.orientation,param.xpos,param.ypos,!param.cropfit); ++ Rotation orientation = param.orientation; ++ if (param.noOrientation && ++ page->is_landscape(param.orientation)) ++ orientation = param.normal_landscape; ++ page->crop(param.page, orientation, param.xpos, param.ypos, ++ !param.cropfit); + } +- param.fitplot = 1; ++ if (param.fillprint) ++ param.fitplot = true; + } + + std::shared_ptr curpage; + int outputpage=0; + int outputno=0; + +- if ((param.nup.nupX==1)&&(param.nup.nupY==1)&&(!param.fitplot)) { +- // TODO? fitplot also without xobject? +- /* +- param.nup.width=param.page.width; +- param.nup.height=param.page.height; +- */ ++ if ((param.nup.nupX == 1) && (param.nup.nupY == 1) && !param.fitplot) ++ { ++ param.nup.width = param.page.width; ++ param.nup.height = param.page.height; ++ } ++ else ++ { ++ param.nup.width = param.page.right - param.page.left; ++ param.nup.height = param.page.top - param.page.bottom; ++ } + +- for (int iA=0;iArotate(param.normal_landscape); ++ param.orientation = param.orientation + param.normal_landscape; ++ // TODO? better ++ if (param.nup.nupX != 1 || param.nup.nupY != 1 || param.fitplot) ++ { ++ xpos = param.page.height - param.page.top; ++ ypos = param.page.left; ++ } ++ std::swap(param.page.width, param.page.height); ++ std::swap(param.nup.width, param.nup.height); ++ } ++ else ++ { ++ if (param.nup.nupX != 1 || param.nup.nupY != 1 || param.fitplot) ++ { ++ xpos = param.page.left; ++ ypos = param.page.bottom; // for whole page... TODO from position... ++ } ++ } + +- if (shuffle[iA]>=numOrigPages) { +- // add empty page as filler +- proc.add_page(proc.new_page(param.page.width,param.page.height),param.reverse); ++ NupState nupstate(param.nup); ++ NupPageEdit pgedit; ++ for (int iA=0;iA page; ++ if (shuffle[iA] >= numOrigPages) ++ // add empty page as filler ++ page=proc.new_page(param.page.width,param.page.height); ++ else ++ page=pages[shuffle[iA]]; ++ ++ PageRect rect; ++ rect = page->getRect(); ++ //rect.dump(); ++ ++ bool newPage=nupstate.nextPage(rect.width,rect.height,pgedit); ++ if (newPage) { ++ if ((curpage)&&(param.withPage(outputpage))) { ++ curpage->rotate(param.orientation); ++ if (param.mirror) ++ curpage->mirror(); ++ // TODO? update rect? --- not needed any more ++ proc.add_page(curpage,param.reverse); // reverse -> insert at beginning ++ // Log page in /var/log/cups/page_log + outputno++; +- continue; // no border, etc. +- } +- auto page=pages[shuffle[iA]]; +- +- page->rotate(param.orientation); +- +- if (param.mirror) { +- page->mirror(); +- } +- +- if (!param.pageLabel.empty()) { +- page->add_label(param.page, param.pageLabel); ++ if (param.page_logging == 1) ++ fprintf(stderr, "PAGE: %d %d\n", outputno, ++ param.copies_to_be_logged); + } +- +- // place border +- if ((param.border!=BorderType::NONE)&&(iAgetRect(); +- +- rect.left+=param.page.left; +- rect.bottom+=param.page.bottom; +- rect.top-=param.page.top; +- rect.right-=param.page.right; +- // width,height not needed for add_border_rect (FIXME?) +- +- page->add_border_rect(rect,param.border,1.0); +-#else // this is what pstops does +- page->add_border_rect(param.page,param.border,1.0); +-#endif +- } +- +- proc.add_page(page,param.reverse); // reverse -> insert at beginning +- outputno++; ++ curpage=proc.new_page(param.page.width,param.page.height); ++ outputpage++; + } +- } else { +- param.nup.width=param.page.right-param.page.left; +- param.nup.height=param.page.top-param.page.bottom; +- +- double xpos=param.page.left, +- ypos=param.page.bottom; // for whole page... TODO from position... +- +- const bool origls=param.nup.landscape; +- if ((param.orientation==ROT_90)||(param.orientation==ROT_270)) { +- std::swap(param.nup.nupX,param.nup.nupY); +- param.nup.landscape=!param.nup.landscape; +- param.orientation=param.orientation-param.normal_landscape; +- } +- if (param.nup.landscape) { +- // pages[iA]->rotate(param.normal_landscape); +- param.orientation=param.orientation+param.normal_landscape; +- // TODO? better +- xpos=param.page.bottom; +- ypos=param.page.width - param.page.right; +- std::swap(param.page.width,param.page.height); +- std::swap(param.nup.width,param.nup.height); ++ if (shuffle[iA]>=numOrigPages) { ++ continue; + } + +- NupState nupstate(param.nup); +- NupPageEdit pgedit; +- for (int iA=0;iA page; +- if (shuffle[iA]>=numOrigPages) { +- // add empty page as filler +- page=proc.new_page(param.page.width,param.page.height); +- } else { +- page=pages[shuffle[iA]]; +- } +- +- PageRect rect; +- if (param.fitplot) { +- rect=page->getRect(); +- } else { +- rect.width=param.page.width; +- rect.height=param.page.height; +- +- // TODO? better +- if (origls) { +- std::swap(rect.width,rect.height); +- } +- +- rect.left=0; +- rect.bottom=0; +- rect.right=rect.width; +- rect.top=rect.height; +- } +- // rect.dump(); +- +- bool newPage=nupstate.nextPage(rect.width,rect.height,pgedit); +- if (newPage) { +- if ((curpage)&&(param.withPage(outputpage))) { +- curpage->rotate(param.orientation); +- if (param.mirror) { +- curpage->mirror(); +- // TODO? update rect? --- not needed any more +- } +- proc.add_page(curpage,param.reverse); // reverse -> insert at beginning +- // Log page in /var/log/cups/page_log +- outputno++; +- if (param.page_logging == 1) +- fprintf(stderr, "PAGE: %d %d\n", outputno, +- param.copies_to_be_logged); +- } +- curpage=proc.new_page(param.page.width,param.page.height); +- outputpage++; +- } +- if (shuffle[iA]>=numOrigPages) { +- continue; +- } +- +- if (param.border!=BorderType::NONE) { +- // TODO FIXME... border gets cutted away, if orignal page had wrong size +- // page->"uncrop"(rect); // page->setMedia() +- // Note: currently "fixed" in add_subpage(...&rect); +- page->add_border_rect(rect,param.border,1.0/pgedit.scale); +- } ++ if (param.border!=BorderType::NONE) { ++ // TODO FIXME... border gets cutted away, if orignal page had wrong size ++ // page->"uncrop"(rect); // page->setMedia() ++ // Note: currently "fixed" in add_subpage(...&rect); ++ page->add_border_rect(rect,param.border,1.0/pgedit.scale); ++ } + +- if (!param.pageLabel.empty()) { +- page->add_label(param.page, param.pageLabel); +- } ++ if (!param.pageLabel.empty()) { ++ page->add_label(param.page, param.pageLabel); ++ } + +- if (!param.fitplot) { +- curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale,&rect); +- } else { +- if(param.cropfit){ +- double xpos2 = (param.page.right-param.page.left-(page->getRect().width))/2; +- double ypos2 = (param.page.top-param.page.bottom-(page->getRect().height))/2; +- if(param.orientation==ROT_270||param.orientation==ROT_90) +- { +- xpos2 = (param.page.right-param.page.left-(page->getRect().height))/2; +- ypos2 = (param.page.top-param.page.bottom-(page->getRect().width))/2; +- curpage->add_subpage(page,ypos2+param.page.bottom,xpos2+param.page.left,1); +- }else{ +- curpage->add_subpage(page,xpos2+param.page.left,ypos2+param.page.bottom,1); +- } +- } +- else +- curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale); ++ if (param.cropfit) ++ { ++ if ((param.nup.nupX == 1) && (param.nup.nupY == 1)) ++ { ++ double xpos2, ypos2; ++ if (param.orientation == ROT_270 || param.orientation == ROT_90) ++ { ++ xpos2 = (param.page.width - (page->getRect().height)) / 2; ++ ypos2 = (param.page.height - (page->getRect().width)) / 2; ++ curpage->add_subpage(page, ypos2 + xpos, xpos2 + ypos, 1); ++ } ++ else ++ { ++ xpos2 = (param.page.width - (page->getRect().width)) / 2; ++ ypos2 = (param.page.height - (page->getRect().height)) / 2; ++ curpage->add_subpage(page, xpos2 + xpos, ypos2 + ypos, 1); ++ } + } ++ else ++ curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale); ++ } ++ else ++ curpage->add_subpage(page, pgedit.xpos + xpos, pgedit.ypos + ypos, ++ pgedit.scale); + + #ifdef DEBUG +- if (auto dbg=dynamic_cast(curpage.get())) { +- // dbg->debug(pgedit.sub,xpos,ypos); +- } ++ if (auto dbg=dynamic_cast(curpage.get())) { ++ dbg->debug(pgedit.sub,xpos,ypos); ++ } + #endif + +- // pgedit.dump(); +- } +- if ((curpage)&&(param.withPage(outputpage))) { +- curpage->rotate(param.orientation); +- if (param.mirror) { +- curpage->mirror(); +- } +- proc.add_page(curpage,param.reverse); // reverse -> insert at beginning +- // Log page in /var/log/cups/page_log +- outputno ++; +- if (param.page_logging == 1) +- fprintf(stderr, "PAGE: %d %d\n", outputno, param.copies_to_be_logged); ++ // pgedit.dump(); ++ } ++ if ((curpage)&&(param.withPage(outputpage))) { ++ curpage->rotate(param.orientation); ++ if (param.mirror) { ++ curpage->mirror(); + } ++ proc.add_page(curpage,param.reverse); // reverse -> insert at beginning ++ // Log page in /var/log/cups/page_log ++ outputno ++; ++ if (param.page_logging == 1) ++ fprintf(stderr, "PAGE: %d %d\n", outputno, param.copies_to_be_logged); + } + + if ((param.evenDuplex || !param.oddPages) && (outputno & 1)) { +diff --git a/filter/pdftopdf/qpdf_pdftopdf_processor.cc b/filter/pdftopdf/qpdf_pdftopdf_processor.cc +index d06ca5f77..621c76880 100644 +--- a/filter/pdftopdf/qpdf_pdftopdf_processor.cc ++++ b/filter/pdftopdf/qpdf_pdftopdf_processor.cc +@@ -179,6 +179,7 @@ void QPDF_PDFTOPDF_PageHandle::add_border_rect(const PageRect &_rect,BorderType + Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale) + { + page.assertInitialized(); ++ Rotation save_rotate = getRotate(page); + if(orientation==ROT_0||orientation==ROT_180) + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_90)); + else +@@ -209,8 +210,8 @@ Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orient + } + } + else{ +- final_w = std::min(width,pageWidth); +- final_h = std::min(height,pageHeight); ++ final_w = pageWidth; ++ final_h = pageHeight; + } + fprintf(stderr,"After Cropping: %lf %lf %lf %lf\n",width,height,final_w,final_h); + double posw = (width-final_w)/2, +@@ -235,13 +236,14 @@ Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orient + //Cropping. + // TODO: Borders are covered by the image. buffer space? + page.replaceKey("/TrimBox",makeBox(currpage.left,currpage.bottom,currpage.right,currpage.top)); +- page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_0)); ++ page.replaceOrRemoveKey("/Rotate",makeRotate(save_rotate)); + return getRotate(page); + } + + bool QPDF_PDFTOPDF_PageHandle::is_landscape(Rotation orientation) + { + page.assertInitialized(); ++ Rotation save_rotate = getRotate(page); + if(orientation==ROT_0||orientation==ROT_180) + page.replaceOrRemoveKey("/Rotate",makeRotate(ROT_90)); + else +@@ -250,6 +252,7 @@ bool QPDF_PDFTOPDF_PageHandle::is_landscape(Rotation orientation) + PageRect currpage= getBoxAsRect(getTrimBox(page)); + double width = currpage.right-currpage.left; + double height = currpage.top-currpage.bottom; ++ page.replaceOrRemoveKey("/Rotate",makeRotate(save_rotate)); + if(width>height) + return true; + return false; +-- +2.47.1 + diff --git a/SOURCES/0001-pdftopdf-Set-a-default-for-print-scaling.patch b/SOURCES/0001-pdftopdf-Set-a-default-for-print-scaling.patch new file mode 100644 index 0000000..456110f --- /dev/null +++ b/SOURCES/0001-pdftopdf-Set-a-default-for-print-scaling.patch @@ -0,0 +1,36 @@ +From 02e95494b49775e9e314d32d78568058d67c9b25 Mon Sep 17 00:00:00 2001 +From: Till Kamppeter +Date: Thu, 3 Feb 2022 19:03:00 -0300 +Subject: [PATCH] pdftopdf: Set a default for "print-scaling" + +If no setting for "print-scaling" is provided via IPP attribute or +command line option there is no default value for it and we get +undefined behavior and also a scary "should never happen" message in +the log. + +Now we check after parsing the appropriate IPP attributes and command +line options whether a setting was provided. If not, we use "auto". + +(manually backported commit dce6292f81b6872656cfcc46dac2ec101c32bf4a) +--- + NEWS | 2 ++ + filter/pdftopdf/pdftopdf.cc | 3 +++ + 2 files changed, 5 insertions(+) + +diff --git a/filter/pdftopdf/pdftopdf.cc b/filter/pdftopdf/pdftopdf.cc +index c6f9d5004..7a684a260 100644 +--- a/filter/pdftopdf/pdftopdf.cc ++++ b/filter/pdftopdf/pdftopdf.cc +@@ -357,6 +357,9 @@ void getParameters(ppd_file_t *ppd,int num_options,cups_option_t *options,Proces + param.cropfit=1; + } + } ++ if (!param.autoprint && !param.autofit && !param.fitplot && ++ !param.fillprint && !param.cropfit) ++ param.autoprint = true; + } + + if (ppd && (ppd->landscape < 0)) { // direction the printer rotates landscape (90 or -90) +-- +2.47.1 + diff --git a/SOURCES/browsed-ignore-NULL-attrs.patch b/SOURCES/browsed-ignore-NULL-attrs.patch new file mode 100644 index 0000000..7fd8666 --- /dev/null +++ b/SOURCES/browsed-ignore-NULL-attrs.patch @@ -0,0 +1,31 @@ +diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c +index 6dba2ed..a5e5779 100644 +--- a/utils/cups-browsed.c ++++ b/utils/cups-browsed.c +@@ -5641,6 +5641,12 @@ record_printer_options(const char *printer) { + printer); + attr = ippFirstAttribute(response); + while (attr) { ++ if (ippGetValueTag(attr) == IPP_TAG_NOVALUE) ++ { ++ attr = ippNextAttribute(response); ++ continue; ++ } ++ + key = ippGetName(attr); + for (ptr = attrs_to_record; *ptr; ptr++) + if (strcasecmp(key, *ptr) == 0 || +@@ -5657,6 +5663,13 @@ record_printer_options(const char *printer) { + memmove(c, c + 1, strlen(c)); + if (*c) c ++; + } ++ ++ if (strlen(buf) == 0) ++ { ++ attr = ippNextAttribute(response); ++ continue; ++ } ++ + debug_printf(" %s=%s\n", key, buf); + p->num_options = cupsAddOption(key, buf, p->num_options, + &(p->options)); diff --git a/SOURCES/cups-filters-CVE-2024-47175.patch b/SOURCES/cups-filters-CVE-2024-47175.patch new file mode 100644 index 0000000..215cd65 --- /dev/null +++ b/SOURCES/cups-filters-CVE-2024-47175.patch @@ -0,0 +1,376 @@ +diff --git a/cupsfilters/ppdgenerator.c b/cupsfilters/ppdgenerator.c +index 4e16383..1f3a7d8 100644 +--- a/cupsfilters/ppdgenerator.c ++++ b/cupsfilters/ppdgenerator.c +@@ -92,6 +92,7 @@ typedef struct _pwg_finishings_s /**** PWG finishings mapping data ****/ + static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize); + static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, + int *xres, int *yres, char *name, size_t namesize); ++static void ppd_put_string(cups_file_t *fp, cups_lang_t *lang, const char *ppd_option, const char *ppd_choice, const char *pwg_msgid); + + /* + * '_cupsSetError()' - Set the last PPD generator status-message. +@@ -1581,9 +1582,10 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + 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 = 0, /* Number of values */ + bottom, /* Largest bottom margin */ +@@ -1663,6 +1665,68 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + return (NULL); + } + ++ // ++ // Get a sanitized make and model... ++ // ++ ++ if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL && ippValidateAttribute(attr)) ++ { ++ // Sanitize the model name to only contain PPD-safe characters. ++ 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 ++ { ++ // Use a default make and model... ++ strlcpy(make, "Unknown", sizeof(make)); ++ } ++ ++ if (!strncasecmp(make, "Hewlett Packard ", 16) || !strncasecmp(make, "Hewlett-Packard ", 16)) ++ { ++ // Normalize HP printer make and model... ++ model = make + 16; ++ strlcpy(make, "HP", sizeof(make)); ++ ++ if (!strncasecmp(model, "HP ", 3)) ++ model += 3; ++ } ++ else if ((mptr = strchr(make, ' ')) != NULL) ++ { ++ // Separate "MAKE MODEL"... ++ while (*mptr && *mptr == ' ') ++ *mptr++ = '\0'; ++ ++ model = mptr; ++ } ++ else ++ { ++ // No separate model name... ++ model = "Printer"; ++ } ++ + /* + * Standard stuff for PPD file... + */ +@@ -1682,24 +1746,6 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + ippContainsString(attr, "faxout")) + is_fax = 1; + +- if ((attr = ippFindAttribute(response, "printer-make-and-model", +- IPP_TAG_TEXT)) != NULL) +- strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make)); +- else if (make_model && make_model[0] != '\0') +- strlcpy(make, make_model, sizeof(make)); +- else +- strlcpy(make, "Unknown Printer", sizeof(make)); +- +- if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) || +- !_cups_strncasecmp(make, "Hewlett-Packard ", 16)) { +- model = make + 16; +- strlcpy(make, "HP", sizeof(make)); +- } +- else if ((model = strchr(make, ' ')) != NULL) +- *model++ = '\0'; +- else +- model = make; +- + cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make); + cupsFilePrintf(fp, "*ModelName: \"%s %s\"\n", make, model); + cupsFilePrintf(fp, "*Product: \"(%s %s)\"\n", make, model); +@@ -1796,14 +1842,11 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + cupsFilePuts(fp, "*cupsSNMPSupplies: False\n"); + cupsFilePuts(fp, "*cupsLanguages: \"en\"\n"); + +- if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != +- NULL) ++ if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != NULL && ippValidateAttribute(attr)) + cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL)); + +- if ((attr = ippFindAttribute(response, "printer-charge-info-uri", +- IPP_TAG_URI)) != NULL) +- cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, +- NULL)); ++ if ((attr = ippFindAttribute(response, "printer-charge-info-uri", IPP_TAG_URI)) != NULL && ippValidateAttribute(attr)) ++ cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL)); + + /* Message catalogs for UI strings */ + if (opt_strings_catalog == NULL) { +@@ -1811,7 +1854,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + load_opt_strings_catalog(NULL, opt_strings_catalog); + } + if ((attr = ippFindAttribute(response, "printer-strings-uri", +- IPP_TAG_URI)) != NULL) { ++ IPP_TAG_URI)) != NULL && ippValidateAttribute(attr)) ++ { + printer_opt_strings_catalog = optArrayNew(); + load_opt_strings_catalog(ippGetString(attr, 0, NULL), + printer_opt_strings_catalog); +@@ -2553,13 +2597,15 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + break; + } + if (j >= 0) +- cupsFilePrintf(fp, "*InputSlot %s/%s: \"<>setpagedevice\"\n", +- ppdname, human_readable, j); ++ { ++ cupsFilePrintf(fp, "*InputSlot %s: \"<>setpagedevice\"\n", ppdname, j); ++ ppd_put_string(fp, lang, "InputSlot", ppdname, human_readable); ++ } + else +- cupsFilePrintf(fp, "*InputSlot %s%s%s: \"\"\n", +- ppdname, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ { ++ cupsFilePrintf(fp, "*InputSlot %s%s%s:\"\"\n", ppdname, human_readable ? "/" : "", human_readable ? human_readable : ""); ++ ppd_put_string(fp, lang, "InputSlot", ppdname, human_readable); ++ } + } + cupsFilePuts(fp, "*CloseUI: *InputSlot\n"); + } +@@ -2743,11 +2789,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, media_types[j][1]); + break; + } +- cupsFilePrintf(fp, "*MediaType %s%s%s: \"<>setpagedevice\"\n", +- ppdname, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : ""), +- ppdname); ++ cupsFilePrintf(fp, "*MediaType %s: \"<>setpagedevice\"\n", ppdname, ppdname); ++ ppd_put_string(fp, lang, "MediaType", ppdname, human_readable); + } + cupsFilePuts(fp, "*CloseUI: *MediaType\n"); + } +@@ -3184,10 +3227,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, output_bins[j][1]); + break; + } +- cupsFilePrintf(fp, "*OutputBin %s%s%s: \"\"\n", +- ppdname, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ cupsFilePrintf(fp, "*OutputBin %s: \"\"\n", ppdname); ++ ppd_put_string(fp, lang, "OutputBin", ppdname, human_readable); + outputorderinfofound = 0; + faceupdown = 1; + firsttolast = 1; +@@ -3425,9 +3466,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, finishings[j][1]); + break; + } +- cupsFilePrintf(fp, "*StapleLocation %s%s%s: \"\"\n", ppd_keyword, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", ppd_keyword); ++ ppd_put_string(fp, lang, "StapleLocation", ppd_keyword, human_readable); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", + value, keyword, ppd_keyword); + } +@@ -3518,9 +3558,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, finishings[j][1]); + break; + } +- cupsFilePrintf(fp, "*FoldType %s%s%s: \"\"\n", ppd_keyword, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ cupsFilePrintf(fp, "*FoldType %s: \"\"\n", ppd_keyword); ++ ppd_put_string(fp, lang, "FoldType", ppd_keyword, human_readable); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", + value, keyword, ppd_keyword); + } +@@ -3618,9 +3657,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, finishings[j][1]); + break; + } +- cupsFilePrintf(fp, "*PunchMedia %s%s%s: \"\"\n", ppd_keyword, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", ppd_keyword); ++ ppd_put_string(fp, lang, "PunchMedia", ppd_keyword, human_readable); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", + value, keyword, ppd_keyword); + } +@@ -3711,9 +3749,8 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + human_readable = (char *)_cupsLangString(lang, finishings[j][1]); + break; + } +- cupsFilePrintf(fp, "*CutMedia %s%s%s: \"\"\n", ppd_keyword, +- (human_readable ? "/" : ""), +- (human_readable ? human_readable : "")); ++ cupsFilePrintf(fp, "*CutMedia %s: \"\"\n", ppd_keyword); ++ ppd_put_string(fp, lang, "CutMedia", ppd_keyword, human_readable); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*CutMedia %s\"\n", + value, keyword, ppd_keyword); + } +@@ -3759,8 +3796,9 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + printer_opt_strings_catalog); + if (human_readable == NULL) + human_readable = (char *)keyword; +- cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\n", keyword, +- human_readable); ++ pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); ++ cupsFilePrintf(fp, "*cupsFinishingTemplate %s: \"\n", ppdname); ++ ppd_put_string(fp, lang, "cupsFinishingTemplate", ppdname, human_readable); + for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr; + finishing_attr = ippNextAttribute(finishing_col)) { + if (ippGetValueTag(finishing_attr) == IPP_TAG_BEGIN_COLLECTION) { +@@ -4072,13 +4110,11 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + if (!preset || !preset_name) + continue; + +- if ((localized_name = lookup_option((char *)preset_name, +- opt_strings_catalog, +- printer_opt_strings_catalog)) == NULL) +- cupsFilePrintf(fp, "*APPrinterPreset %s: \"\n", preset_name); +- else +- cupsFilePrintf(fp, "*APPrinterPreset %s/%s: \"\n", preset_name, +- localized_name); ++ pwg_ppdize_name(preset_name, ppdname, sizeof(ppdname)); ++ ++ localized_name = lookup_option((char *)preset_name, opt_strings_catalog, printer_opt_strings_catalog); ++ cupsFilePrintf(fp, "*APPrinterPreset %s: \"\n", ppdname); ++ ppd_put_string(fp, lang, "APPrinterPreset", ppdname, localized_name); + + for (member = ippFirstAttribute(preset); member; + member = ippNextAttribute(preset)) { +@@ -4119,7 +4155,10 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + ippGetString(ippFindAttribute(fin_col, + "finishing-template", + IPP_TAG_ZERO), 0, NULL)) != NULL) +- cupsFilePrintf(fp, "*cupsFinishingTemplate %s\n", keyword); ++ { ++ pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); ++ cupsFilePrintf(fp, "*cupsFinishingTemplate %s\n", ppdname); ++ } + } + } else if (!strcmp(member_name, "media")) { + /* +@@ -4152,14 +4191,14 @@ ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */ + IPP_TAG_ZERO), 0, + NULL)) != NULL) { + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); +- cupsFilePrintf(fp, "*InputSlot %s\n", keyword); ++ cupsFilePrintf(fp, "*InputSlot %s\n", ppdname); + } + + if ((keyword = ippGetString(ippFindAttribute(media_col, "media-type", + IPP_TAG_ZERO), 0, + NULL)) != NULL) { + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); +- cupsFilePrintf(fp, "*MediaType %s\n", keyword); ++ cupsFilePrintf(fp, "*MediaType %s\n", ppdname); + } + } else if (!strcmp(member_name, "print-quality")) { + /* +@@ -4422,15 +4461,28 @@ pwg_ppdize_name(const char *ipp, /* I - IPP keyword */ + *end; /* End of name buffer */ + + ++ if (!ipp || !_cups_isalnum(*ipp)) ++ { ++ *name = '\0'; ++ return; ++ } ++ + *name = (char)toupper(*ipp++); + + for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;) { +- if (*ipp == '-') { ++ if (*ipp == '-' && isalnum(ipp[1])) ++ { + ipp ++; +- if (_cups_isalpha(*ipp)) +- *ptr++ = (char)toupper(*ipp++ & 255); +- } else ++ *ptr++ = (char)toupper(*ipp++ & 255); ++ } ++ else if (*ipp == '_' || *ipp == '.' || *ipp == '-' || isalnum(*ipp)) ++ { + *ptr++ = *ipp++; ++ } ++ else ++ { ++ ipp ++; ++ } + } + + *ptr = '\0'; +@@ -4467,4 +4519,39 @@ pwg_ppdize_resolution( + snprintf(name, namesize, "%dx%ddpi", *xres, *yres); + } + } ++ ++ ++/* ++ * 'ppd_put_strings()' - Write localization attributes to a PPD file. ++ */ ++ ++static void ++ppd_put_string(cups_file_t *fp, /* I - PPD file */ ++ cups_lang_t *lang, /* I - Language */ ++ const char *ppd_option,/* I - PPD option */ ++ const char *ppd_choice,/* I - PPD choice */ ++ const char *text) /* I - Localized text */ ++{ ++ if (!text) ++ return; ++ ++ // Add the first line of localized text... ++#if CUPS_VERSION_MAJOR > 2 ++ cupsFilePrintf(fp, "*%s.%s %s/", cupsLangGetName(lang), ppd_option, ppd_choice); ++#else ++ cupsFilePrintf(fp, "*%s.%s %s/", lang->language, ppd_option, ppd_choice); ++#endif // CUPS_VERSION_MAJOR > 2 ++ ++ while (*text && *text != '\n') ++ { ++ // Escape ":" and "<"... ++ if (*text == ':' || *text == '<') ++ cupsFilePrintf(fp, "<%02X>", *text); ++ else ++ cupsFilePutChar(fp, *text); ++ ++ text ++; ++ } ++ cupsFilePuts(fp, ": \"\"\n"); ++} + #endif /* HAVE_CUPS_1_6 */ diff --git a/SPECS/cups-filters.spec b/SPECS/cups-filters.spec index ab96a43..034180d 100644 --- a/SPECS/cups-filters.spec +++ b/SPECS/cups-filters.spec @@ -11,7 +11,7 @@ Summary: OpenPrinting CUPS filters and backends Name: cups-filters Version: 1.28.7 -Release: 15%{?dist} +Release: 20%{?dist} # For a breakdown of the licensing, see COPYING file # GPLv2: filters: commandto*, imagetoraster, pdftops, rasterto*, @@ -42,6 +42,23 @@ Patch03: 0001-libcupsfilters-Fix-page-range-like-10-in-pdftopdf-fi.patch Patch04: beh-cve2023.patch # RHEL-16026 Cups Browsed does not correctly pull printer location and description information from print server Patch05: 0001-Use-description-location-from-server-if-available-ot.patch +# RHEL-46785 Cups browsing with 'Autoclustering on' in RHEL 9 cannot find printer clusters for HA +Patch06: browsed-ignore-NULL-attrs.patch +# CVE-2024-47175 cups-filters: remote command injection via attacker controlled data in PPD file +Patch07: cups-filters-CVE-2024-47175.patch +# CVE-2024-47076 cups-filters: `cfGetPrinterAttributes` API does not perform sanitization on returned IPP attributes +Patch08: 0001-cfGetPrinterAttributes5-Validate-response-attributes.patch +# RHEL-17124 [cups-browsed] Prints to remote RAW queues are converted to PDF documents +Patch09: 0001-Do-not-generate-PPD-for-remote-raw-queues-44.patch +# RHEL-70015 Double-sided printing issues on Thunderbird or Firefox // HP printers +# Patches: 0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patcj +# 0001-pdftopdf-Set-a-default-for-print-scaling.patch +# 0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch +# 0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch +Patch10: 0001-pdftopdf-Fixed-print-scaling-and-N-up-for-asymmetric.patch +Patch11: 0001-pdftopdf-Set-a-default-for-print-scaling.patch +Patch12: 0001-pdftopdf-Add-2-tolerance-for-input-size-larger-than-.patch +Patch13: 0001-libcupsfilters-In-pdftopdf-fix-cropping-with-long-ed.patch # autogen.sh @@ -222,6 +239,7 @@ The package provides filters and cups-brf backend needed for braille printing. %else --disable-braille \ %endif + --with-browseremoteprotocols=none\ --with-remote-cups-local-queue-naming=RemoteName %make_build @@ -275,6 +293,14 @@ do fi done +# Set BrowseRemoteProtocols to none in light of CVE-2024-47176 +if ! grep -Fxq "# added by post scriptlet" %{_sysconfdir}/cups/cups-browsed.conf +then + cp %{_sysconfdir}/cups/cups-browsed.conf %{_sysconfdir}/cups/cups-browsed.conf.rpmsave + sed -i "s/^\s*BrowseRemoteProtocols.*/# added by post scriptlet\nBrowseRemoteProtocols none/" %{_sysconfdir}/cups/cups-browsed.conf +fi + + %preun %systemd_preun cups-browsed.service @@ -283,6 +309,38 @@ done %ldconfig_scriptlets libs +%posttrans +if ls -lah /var/cache/cups/cups-browsed* &> /dev/null +then + BROWSED_ACTIVE="0" + CUPSD_ACTIVE="0" + + if systemctl is-active cups-browsed &> /dev/null + then + BROWSED_ACTIVE="1" + CUPSD_ACTIVE="1" + elif systemctl is-active cups &> /dev/null + then + CUPSD_ACTIVE="1" + fi + + if test "x$CUPSD_ACTIVE" = "x1" + then + systemctl stop cups + fi + + # RHEL-46785 - clean up recorded options to make the fix work + rm -rf /var/cache/cups/*.data /var/cache/cups/cups-browsed* &> /dev/null + + if test "x$BROWSED_ACTIVE" = "x1" + then + systemctl start cups-browsed + elif test "x$CUPSD_ACTIVE" = "x1" + then + systemctl start cups + fi +fi + %files %{_pkgdocdir}/README @@ -343,7 +401,7 @@ done %{_mandir}/man1/driverless.1.gz %{_mandir}/man5/cups-browsed.conf.5.gz %{_mandir}/man8/cups-browsed.8.gz -%config(noreplace) %{_sysconfdir}/cups/cups-browsed.conf +%config(noreplace) %verify(not size filedigest mtime) %{_sysconfdir}/cups/cups-browsed.conf %{_unitdir}/cups-browsed.service %files libs @@ -407,6 +465,23 @@ done %endif %changelog +* Thu Dec 12 2024 Zdenek Dohnal - 1.28.7-20 +- RHEL-70015 Double-sided printing issues on Thunderbird or Firefox // HP printers + +* Tue Oct 15 2024 Zdenek Dohnal - 1.28.7-19 +- RHEL-17124 [cups-browsed] Prints to remote RAW queues are converted to PDF documents + +* Tue Oct 01 2024 Zdenek Dohnal - 1.28.7-18 +- CVE-2024-47175 cups-filters: remote command injection via attacker controlled data in PPD file +- CVE-2024-47076 cups-filters: `cfGetPrinterAttributes` API does not perform sanitization on returned IPP attributes +- CVE-2024-47176 cups-filters: cups-browsed binds on UDP INADDR_ANY:631 trusting any packet from any source + +* Tue Aug 06 2024 Zdenek Dohnal - 1.28.7-17 +- RHEL-46785 - fix errors during installability tests about modified cups-browsed.conf + +* Tue Jul 30 2024 Zdenek Dohnal - 1.28.7-16 +- RHEL-46785 Cups browsing with 'Autoclustering on' in RHEL 9 cannot find printer clusters for HA + * Mon Feb 26 2024 Zdenek Dohnal - 1.28.7-15 - RHEL-19201 redhat-lsb unnecessary pulls in cups and avahi dependencies