From c10d17dee78d48d5e56da965e0cd02d28fd513a5 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 9 Dec 2020 17:42:53 +0000 Subject: [PATCH] FPDF_GetTrailerEnds: make this not depend on whitespace PDF-1.7 calls out no bytes other than whitespace when specifying what can occur between endstream and endobj, so whitespace needs to be handled. When CPDF_SyntaxParser::ReadStream() reads the stream, it reads 'endobj', and then resets the position back to the end of 'endstream'. This mechanism is disabled in case there is whitespace between the tokens and the newline, see the end of the function. This results in reporting no trailer ends, as the parsing fails, as the next token is expected to be 'endobj', but it's the ID of the next object instead. Fix the problem by handling whitespace in CPDF_SyntaxParser::ReadStream() where it was looking for \ntoken\n, not allowing whitespace between the token and the following newline. Change-Id: I7048e8d081af04af3dd08d957212c885b7982b5e Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/76850 Commit-Queue: Tom Sepez Reviewed-by: Tom Sepez --- core/fpdfapi/parser/cpdf_syntax_parser.cpp | 8 ++ fpdfsdk/fpdf_view_embeddertest.cpp | 14 +++ .../resources/trailer_end_trailing_space.in | 86 ++++++++++++++++ .../resources/trailer_end_trailing_space.pdf | 99 +++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 testing/resources/trailer_end_trailing_space.in create mode 100644 testing/resources/trailer_end_trailing_space.pdf diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index 06389bccc..5318efdc1 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -795,6 +795,14 @@ RetainPtr CPDF_SyntaxParser::ReadStream( memset(m_WordBuffer, 0, kEndObjStr.GetLength() + 1); GetNextWordInternal(nullptr); + // Allow whitespace after endstream and before a newline. + unsigned char ch = 0; + while (GetNextChar(ch)) { + if (!PDFCharIsWhitespace(ch) || PDFCharIsLineEnding(ch)) + break; + } + SetPos(GetPos() - 1); + int numMarkers = ReadEOLMarkers(GetPos()); if (m_WordSize == static_cast(kEndObjStr.GetLength()) && numMarkers != 0 && -- 2.26.2