0

[PrintBackend] Skip Papers with empty page sizes

For Windows and CUPS IPP, PrintBackend is able to add Papers with empty
page sizes. This used to be filtered out when converting a Paper into a
Media object, but now that we have strengthened the Mojo validation
conditions to disallow empty page sizes, users are encountering crashes.

Since we used to drop Papers with empty page sizes after the conversion
anyway, skip any Papers with empty page sizes.

Also, remove a single instance of an unnecessary explicit conversion
to std::string.

Bug: 1416294, 1412305
Change-Id: I608cf931f84588e65098eb6964cbe2b56e3f2f63
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4257595
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Andy Phan <andyphan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1106525}
This commit is contained in:
Andy Phan
2023-02-17 00:24:02 +00:00
committed by Chromium LUCI CQ
parent 3e08d37c08
commit 7e4a968190
5 changed files with 22 additions and 21 deletions

@ -340,8 +340,7 @@ PrinterSemanticCapsAndDefaults::Paper DefaultPaper(const CupsPrinter& printer) {
return PrinterSemanticCapsAndDefaults::Paper();
}
return ParsePaper(media_name,
printer.GetMediaMarginsByName(std::string(media_name)));
return ParsePaper(media_name, printer.GetMediaMarginsByName(media_name));
}
void CapsAndDefaultsFromPrinter(const CupsPrinter& printer,

@ -119,6 +119,9 @@ PrinterSemanticCapsAndDefaults::Paper ParsePaper(
PrinterSemanticCapsAndDefaults::Paper paper;
paper.vendor_id = std::string(value);
paper.size_um = DimensionsToMicrons(dimensions);
if (paper.size_um.IsEmpty()) {
return PrinterSemanticCapsAndDefaults::Paper();
}
// The margins of the printable area are expressed in PWG units (100ths of
// mm).

@ -35,7 +35,8 @@ gfx::Size ParsePaperSize(base::StringPiece value);
#if BUILDFLAG(USE_CUPS)
// Parses the media name expressed by `value` into a Paper. Returns an
// empty Paper if `value` does not contain the display name nor the dimension,
// or if `value` contains a prefix of media sizes not meant for users' eyes.
// `value` contains a prefix of media sizes not meant for users' eyes, or if the
// paper size is empty.
// `margins` is used to calculate the Paper's printable area.
// We don't handle l10n here. We do populate the display_name member with the
// prettified vendor ID, but fully expect the caller to clobber this if a better

@ -103,19 +103,13 @@ TEST(PrintBackendUtilsCupsTest, ParsePaperNaNumber10) {
TEST(PrintBackendUtilsCupsTest, ParsePaperBadUnit) {
PrinterSemanticCapsAndDefaults::Paper paper_bad =
ParsePaper("bad_unit_666x666bad", CupsPrinter::CupsMediaMargins());
EXPECT_TRUE(paper_bad.size_um.IsEmpty());
EXPECT_EQ("bad_unit_666x666bad", paper_bad.vendor_id);
EXPECT_EQ("bad unit", paper_bad.display_name);
EXPECT_EQ(gfx::Rect(), paper_bad.printable_area_um);
EXPECT_EQ(PrinterSemanticCapsAndDefaults::Paper(), paper_bad);
}
TEST(PrintBackendUtilsCupsTest, ParsePaperBadOneDimension) {
PrinterSemanticCapsAndDefaults::Paper paper_bad =
ParsePaper("bad_one_dimension_666mm", CupsPrinter::CupsMediaMargins());
EXPECT_TRUE(paper_bad.size_um.IsEmpty());
EXPECT_EQ("bad_one_dimension_666mm", paper_bad.vendor_id);
EXPECT_EQ("bad one dimension", paper_bad.display_name);
EXPECT_EQ(gfx::Rect(), paper_bad.printable_area_um);
EXPECT_EQ(PrinterSemanticCapsAndDefaults::Paper(), paper_bad);
}
TEST(PrintBackendUtilsCupsTest, ParsePaperOutOfBoundsMargins) {
@ -142,15 +136,13 @@ TEST(PrintBackendUtilsCupsTest, ParsePaperEmptyPrintableArea) {
EXPECT_EQ(gfx::Rect(0, 0, 210000, 297000), paper.printable_area_um);
}
TEST(PrintBackendUtilsCupsTest, ParsePaperEmptySize) {
// If the paper size is empty, the printable area should also be empty.
TEST(PrintBackendUtilsCupsTest, ParsePaperEmptySizeWithPrintableArea) {
// If the paper size is empty, the Paper should be invalid, even when provided
// a printable area.
constexpr CupsPrinter::CupsMediaMargins kMargins = {1000, 1000, 1000, 1000};
PrinterSemanticCapsAndDefaults::Paper paper_bad =
ParsePaper("bad_unit_666x666bad", kMargins);
EXPECT_TRUE(paper_bad.size_um.IsEmpty());
EXPECT_EQ("bad_unit_666x666bad", paper_bad.vendor_id);
EXPECT_EQ("bad unit", paper_bad.display_name);
EXPECT_EQ(gfx::Rect(), paper_bad.printable_area_um);
EXPECT_EQ(PrinterSemanticCapsAndDefaults::Paper(), paper_bad);
}
#endif // BUILDFLAG(USE_CUPS)

@ -164,6 +164,12 @@ void LoadPaper(const wchar_t* printer,
for (size_t i = 0; i < sizes.size(); ++i) {
PrinterSemanticCapsAndDefaults::Paper paper;
paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm);
// Skip papers with empty paper sizes.
if (paper.size_um.IsEmpty()) {
continue;
}
if (!names.empty()) {
const wchar_t* name_start = names[i].chars;
std::wstring tmp_name(name_start, kMaxPaperName);
@ -200,10 +206,10 @@ void LoadPaper(const wchar_t* printer,
// Copy paper with the same ID as default paper.
if (devmode->dmFields & DM_PAPERSIZE) {
for (size_t i = 0; i < ids.size(); ++i) {
if (ids[i] == devmode->dmPaperSize) {
DCHECK_EQ(ids.size(), caps->papers.size());
caps->default_paper = caps->papers[i];
std::string default_vendor_id = base::NumberToString(devmode->dmPaperSize);
for (const PrinterSemanticCapsAndDefaults::Paper& paper : caps->papers) {
if (paper.vendor_id == default_vendor_id) {
caps->default_paper = paper;
break;
}
}