crashtesting: keep a page that pdfium cannot read in the import
reproduce by converting the crashtesting document bitmapreadaccess_getpixelforn24bittcbgr_segmentation_fault.sample, which is a pdf despite its name, to odg: soffice.bin: sd/source/filter/pdf/sdpdffilter.cxx:102: bool ImportPDF(...): Assertion `nPageNumber >= 0 && o3tl::make_unsigned(nPageNumber) < aGraphics.size()' failed. pdfium cannot read three of the five pages here. Both the page size by index and the page itself fail, so this isn't our size test being too strict. The file is fuzzed, mutool reports a broken xref and an invalid object number, and one MediaBox reads [ 1612934155079108773 0 594 841 ]. ImportPDFUnloaded dropped each page that it couldn't read, so a five page pdf became a two page Draw document with nothing to say three pages were lost. The graphics that remained kept their own pdf page numbers, which then had gaps, and the last one pointed past the end. Keep an entry for every page the pdf declares. Such a page takes the size of the last page that did come through, A4 to start, and warns. It still carries its own page number, so there are no gaps left for sd to trip over. Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com> Change-Id: Id0d0bde13a2102b4e30cc0dd71edf17031406e1d Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5639 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Noel Grandin <noel.grandin@collabora.com> (cherry picked from commit 321ab2f58f62bf3037ee32e1696bacd14c8f06ed) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211020 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
6451dfad11
commit
949b19a363
@@ -425,37 +425,47 @@ ImportPDFUnloaded(SvStream& rStream, std::vector<PDFGraphicResult>& rGraphics,
|
||||
if (nPageCount <= 0)
|
||||
return 0;
|
||||
|
||||
// A page pdfium cannot read still gets an entry, so the result keeps one page per page the
|
||||
// pdf declares and every entry knows its own page number. Such a page takes the size of the
|
||||
// last page that did come through, starting at A4 in 1/100 mm.
|
||||
Size aLastGoodSize(21000, 29700);
|
||||
|
||||
for (int nPageIndex = 0; nPageIndex < nPageCount; ++nPageIndex)
|
||||
{
|
||||
basegfx::B2DSize aPageSize = pPdfDocument->getPageSize(nPageIndex);
|
||||
if (aPageSize.getWidth() <= 0.0 || aPageSize.getHeight() <= 0.0)
|
||||
continue;
|
||||
|
||||
// Returned unit is points
|
||||
basegfx::B2DSize aPageSize = pPdfDocument->getPageSize(nPageIndex);
|
||||
|
||||
std::unique_ptr<vcl::pdf::PDFiumPage> pPage;
|
||||
if (aPageSize.getWidth() > 0.0 && aPageSize.getHeight() > 0.0)
|
||||
pPage = pPdfDocument->openPage(nPageIndex);
|
||||
|
||||
if (!pPage)
|
||||
{
|
||||
SAL_WARN("vcl.filter",
|
||||
"ImportPDF: page " << nPageIndex << " is unreadable, importing it blank");
|
||||
rGraphics.emplace_back(Graphic(pGfxLink, nPageIndex), aLastGoodSize,
|
||||
std::vector<PDFGraphicAnnotation>(),
|
||||
std::vector<std::pair<basegfx::B2DRectangle, OUString>>());
|
||||
continue;
|
||||
}
|
||||
|
||||
tools::Long nPageWidth = std::round(convertPointToMm100(aPageSize.getWidth()));
|
||||
tools::Long nPageHeight = std::round(convertPointToMm100(aPageSize.getHeight()));
|
||||
aLastGoodSize = Size(nPageWidth, nPageHeight);
|
||||
|
||||
// Create the Graphic with the VectorGraphicDataPtr and link the original PDF stream.
|
||||
// We swap out this Graphic as soon as possible, and a later swap in
|
||||
// actually renders the correct Bitmap on demand.
|
||||
Graphic aGraphic(pGfxLink, nPageIndex);
|
||||
|
||||
auto pPage = pPdfDocument->openPage(nPageIndex);
|
||||
if (!pPage)
|
||||
{
|
||||
SAL_WARN("vcl.filter", "ImportPDF: unable to open page: " << nPageIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<PDFGraphicAnnotation> aPDFGraphicAnnotations
|
||||
= findAnnotations(pPage, aPageSize);
|
||||
|
||||
std::vector<std::pair<basegfx::B2DRectangle, OUString>> aPDFLinksInfo
|
||||
= findLinks(pPage, pPdfDocument, aPageSize);
|
||||
|
||||
rGraphics.emplace_back(std::move(aGraphic), Size(nPageWidth, nPageHeight),
|
||||
aPDFGraphicAnnotations, aPDFLinksInfo);
|
||||
rGraphics.emplace_back(std::move(aGraphic), aLastGoodSize, aPDFGraphicAnnotations,
|
||||
aPDFLinksInfo);
|
||||
}
|
||||
|
||||
return rGraphics.size();
|
||||
|
||||
Reference in New Issue
Block a user