poppler/UTF.cc | 2 +- poppler/UTF.h | 2 +- qt5/tests/check_utf_conversion.cpp | 2 +- qt6/tests/check_utf_conversion.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
New commits: commit e885124ab3b071b7fbb2f001e4a9a88b7e758605 Author: Even Rouault <[email protected]> Date: Thu Jun 15 20:25:24 2023 +0200 utf8ToUtf16(): fix out-of-bounds write Fixes a regression introduced by recent 9183da4fcb8d06360ed51f7f1131a14300008735 commit which caused the following Valgrind error: ``` $ valgrind utils/pdftoppm /tmp/test.pdf ==3735668== Memcheck, a memory error detector ==3735668== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==3735668== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==3735668== Command: utils/pdftoppm /tmp/test.pdf ==3735668== Syntax Warning: May not be a PDF file (continuing anyway) Syntax Error: Unterminated string ==3735668== Invalid write of size 2 ==3735668== at 0x4A3570C: utf8ToUtf16(char const*, unsigned short*, int, int) (poppler/UTF.cc:353) ==3735668== by 0x4A3584C: utf8ToUtf16(char const*, int*) (poppler/UTF.cc:368) ==3735668== by 0x4A358D4: utf8ToUtf16WithBom(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (poppler/UTF.cc:379) ==3735668== by 0x49F2C97: Lexer::getObj(int) (poppler/Lexer.cc:424) ==3735668== by 0x4A035C2: Parser::Parser(XRef*, Stream*, bool) (poppler/Parser.cc:50) ==3735668== by 0x49F888B: Linearization::Linearization(BaseStream*) (poppler/Linearization.cc:28) ==3735668== by 0x4A06D8D: getLinearization (poppler/PDFDoc.cc:648) ==3735668== by 0x4A06D8D: PDFDoc::isLinearized(bool) (poppler/PDFDoc.cc:700) ==3735668== by 0x4A0518D: PDFDoc::getStartXRef(bool) (poppler/PDFDoc.cc:2003) ==3735668== by 0x4A04BB8: PDFDoc::setup(std::optional<GooString> const&, std::optional<GooString> const&, std::function<void ()> const&) (poppler/PDFDoc.cc:246) ==3735668== by 0x4A04AAB: PDFDoc::PDFDoc(std::unique_ptr<GooString, std::default_delete<GooString> >&&, std::optional<GooString> const&, std::optional<GooString> const&, void*, std::function<void ()> const&) (poppler/PDFDoc.cc:160) ==3735668== by 0x49F93EA: LocalPDFDocBuilder::buildPDFDoc(GooString const&, std::optional<GooString> const&, std::optional<GooString> const&, void*) (poppler/LocalPDFDocBuilder.cc:0) ==3735668== by 0x4A1FBB5: PDFDocFactory::createPDFDoc(GooString const&, std::optional<GooString> const&, std::optional<GooString> const&, void*) (poppler/PDFDocFactory.cc:62) ==3735668== Address 0x669cf54 is 0 bytes after a block of size 148 alloc'd ==3735668== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==3735668== by 0x4A35815: gmalloc (goo/gmem.h:44) ==3735668== by 0x4A35815: gmallocn (goo/gmem.h:121) ==3735668== by 0x4A35815: utf8ToUtf16(char const*, int*) (poppler/UTF.cc:367) ==3735668== by 0x4A358D4: utf8ToUtf16WithBom(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (poppler/UTF.cc:379) ==3735668== by 0x49F2C97: Lexer::getObj(int) (poppler/Lexer.cc:424) ==3735668== by 0x4A035C2: Parser::Parser(XRef*, Stream*, bool) (poppler/Parser.cc:50) ==3735668== by 0x49F888B: Linearization::Linearization(BaseStream*) (poppler/Linearization.cc:28) ==3735668== by 0x4A06D8D: getLinearization (poppler/PDFDoc.cc:648) ==3735668== by 0x4A06D8D: PDFDoc::isLinearized(bool) (poppler/PDFDoc.cc:700) ==3735668== by 0x4A0518D: PDFDoc::getStartXRef(bool) (poppler/PDFDoc.cc:2003) ==3735668== by 0x4A04BB8: PDFDoc::setup(std::optional<GooString> const&, std::optional<GooString> const&, std::function<void ()> const&) (poppler/PDFDoc.cc:246) ==3735668== by 0x4A04AAB: PDFDoc::PDFDoc(std::unique_ptr<GooString, std::default_delete<GooString> >&&, std::optional<GooString> const&, std::optional<GooString> const&, void*, std::function<void ()> const&) (poppler/PDFDoc.cc:160) ==3735668== by 0x49F93EA: LocalPDFDocBuilder::buildPDFDoc(GooString const&, std::optional<GooString> const&, std::optional<GooString> const&, void*) (poppler/LocalPDFDocBuilder.cc:0) ==3735668== by 0x4A1FBB5: PDFDocFactory::createPDFDoc(GooString const&, std::optional<GooString> const&, std::optional<GooString> const&, void*) (poppler/PDFDocFactory.cc:62) ``` Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59840 diff --git a/poppler/UTF.cc b/poppler/UTF.cc index 8cf8056c..5d971f9d 100644 --- a/poppler/UTF.cc +++ b/poppler/UTF.cc @@ -365,7 +365,7 @@ uint16_t *utf8ToUtf16(const char *utf8, int *len) *len = n; } uint16_t *utf16 = (uint16_t *)gmallocn(n + 1, sizeof(uint16_t)); - utf8ToUtf16(utf8, utf16); + utf8ToUtf16(utf8, utf16, n + 1, INT_MAX); return utf16; } diff --git a/poppler/UTF.h b/poppler/UTF.h index cdcfb57a..8fec5a93 100644 --- a/poppler/UTF.h +++ b/poppler/UTF.h @@ -69,7 +69,7 @@ int POPPLER_PRIVATE_EXPORT utf8CountUtf16CodeUnits(const char *utf8); // maxUtf8 - maximum number of UTF-8 bytes to convert. Conversion stops when // either this count is reached or a null is encountered. // Returns number of UTF-16 code units written (excluding NULL). -int POPPLER_PRIVATE_EXPORT utf8ToUtf16(const char *utf8, uint16_t *utf16, int maxUtf16 = INT_MAX, int maxUtf8 = INT_MAX); +int POPPLER_PRIVATE_EXPORT utf8ToUtf16(const char *utf8, uint16_t *utf16, int maxUtf16, int maxUtf8); // Allocate utf16 string and convert utf8 into it. uint16_t POPPLER_PRIVATE_EXPORT *utf8ToUtf16(const char *utf8, int *len = nullptr); diff --git a/qt5/tests/check_utf_conversion.cpp b/qt5/tests/check_utf_conversion.cpp index 73c684ee..506a2a13 100644 --- a/qt5/tests/check_utf_conversion.cpp +++ b/qt5/tests/check_utf_conversion.cpp @@ -94,7 +94,7 @@ void TestUTFConversion::testUTF() QCOMPARE(len, s.size()); // QString size() returns number of code units, not code points Q_ASSERT(len < (int)sizeof(utf16Buf)); // if this fails, make utf16Buf larger - len = utf8ToUtf16(str, utf16Buf); + len = utf8ToUtf16(str, utf16Buf, sizeof(utf16Buf), INT_MAX); QVERIFY(compare(utf16Buf, s.utf16())); QCOMPARE(len, s.size()); diff --git a/qt6/tests/check_utf_conversion.cpp b/qt6/tests/check_utf_conversion.cpp index 2cac7582..06366724 100644 --- a/qt6/tests/check_utf_conversion.cpp +++ b/qt6/tests/check_utf_conversion.cpp @@ -92,7 +92,7 @@ void TestUTFConversion::testUTF() QCOMPARE(len, s.size()); // QString size() returns number of code units, not code points Q_ASSERT(len < (int)sizeof(utf16Buf)); // if this fails, make utf16Buf larger - len = utf8ToUtf16(str, utf16Buf); + len = utf8ToUtf16(str, utf16Buf, sizeof(utf16Buf), INT_MAX); QVERIFY(compare(utf16Buf, s.utf16())); QCOMPARE(len, s.size());
