diff --git a/cupsfilters/test-filter-cases.txt b/cupsfilters/test-filter-cases.txt index d75f8c573..39097a3fc 100644 --- a/cupsfilters/test-filter-cases.txt +++ b/cupsfilters/test-filter-cases.txt @@ -25,3 +25,4 @@ cupsfilters/test_files/test_text_russian.txt text/plain cupsfilters/test_files/o cupsfilters/test_files/test_text_arabic_rtl.txt text/plain cupsfilters/test_files/output_files/output_text_arabic.pdf application/pdf Generic PDF Color 2 1 1 text/plain,application/pdf 303 arabic-user arabic-test 1 cupsfilters/test_files/malformed.pdf application/pdf cupsfilters/test_files/output_files/output_malformed_should_fail.pdf application/vnd.cups-pdf Generic PDF Color 2 1 1 application/vnd.cups-pdf 202 poc-user-malformed expect-fail 1 +cupsfilters/test_files/test_text_lorem.txt text/plain cupsfilters/test_files/output_files/output_texttotext_page_overflow.txt text/plain Generic PDF Color 2 1 1 text/plain 210 overflow-user texttotext-page-overflow 1 PageWidth=1073741824 PageHeight=1 texttotext diff --git a/cupsfilters/testfilters.c b/cupsfilters/testfilters.c index 9c0e2b27f..22c1c183d 100644 --- a/cupsfilters/testfilters.c +++ b/cupsfilters/testfilters.c @@ -76,6 +76,7 @@ FilterMapping filter_mappings[] = { { "pwgtopdf", cfFilterPWGToPDF, NULL }, { "pdftopdf", cfFilterPDFToPDF, NULL }, { "texttopdf", cfFilterTextToPDF, NULL }, + { "texttotext", cfFilterTextToText, NULL }, }; cups_array_t* diff --git a/cupsfilters/texttotext.c b/cupsfilters/texttotext.c index 0c241174c..b8a6d5354 100644 --- a/cupsfilters/texttotext.c +++ b/cupsfilters/texttotext.c @@ -344,6 +344,26 @@ cfFilterTextToText(int inputfd, // I - File descriptor input stream i, num_columns); } + // "PageWidth"/"PageHeight" (and the num-chars/lines-per-inch options + // above) only get checked against zero, not against any upper bound, so + // a job can ask for a page with billions of columns or lines. The output + // page buffer is sized a few lines down as + // ((num_columns + 2) * num_lines + 2) * 4, computed in a plain int, and + // an oversized request wraps that computation instead of failing it, + // handing the allocation a small size while the rest of the function + // still believes the page is as wide as requested. Reject such requests + // here, before that calculation runs, and fall back to the defaults. + if ((long long)(num_columns + 2) * (long long)num_lines > + (long long)(INT_MAX - 2) / 4) + { + if (log) log(ld, CF_LOGLEVEL_DEBUG, + "cfFilterTextToText: Page of %d columns by %d lines is too " + "large to allocate a page buffer for, using default values: " + "80 x 66", num_columns, num_lines); + num_columns = 80; + num_lines = 66; + } + if (log) log(ld, CF_LOGLEVEL_DEBUG, "cfFilterTextToText: Lines per page: %d; Characters per line: %d", num_lines, num_columns);