Fix signed-to-unsigned conversion bug in PDF text processing
This commit fixes a bug in PDFiumPage where char count of -1 was
incorrectly converted to 4294967295 instead of 0.
A clusterfuzz testcase exposed this vulnerability through a unique PDF
object corruption:
/ProcSet [/PDF/Text/ImageC/Image/Image/Image/Image/Image/Image...
→ thousands of repeated /Image entries
which would lead to a crash:
1. FPDFText_LoadPage() fails when parsing malformed structures, returns nullptr
2. FPDFText_CountChars(nullptr), returns -1
3. CalculateTextRuns() converts -1 to uint32_t, becomes 4294967295
(not 0 as stated in the comment!)
4. GetTextRunInfoAt() returns empty optional for invalid indices
5. Calling .value() on empty optional, crash
Bug: 447520186
Change-Id: Ide75829d73002c32b3e6d360ce6183a62c75d7b6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6995201
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1522295}
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc
index 30b3290f..2a23d24 100644
--- a/pdf/pdfium/pdfium_page.cc
+++ b/pdf/pdfium/pdfium_page.cc
@@ -513,7 +513,8 @@
const int raw_char_count = GetCharCount();
// Treat a char count of -1 (error) as 0 (an empty page), since
// other pages might have valid content.
- const uint32_t char_count = std::max<uint32_t>(raw_char_count, 0);
+ const uint32_t char_count =
+ raw_char_count < 0 ? 0 : static_cast<uint32_t>(raw_char_count);
std::vector<AccessibilityCharInfo> chars(char_count);
for (uint32_t i = 0; i < char_count; ++i) {
@@ -1263,7 +1264,8 @@
const int raw_char_count = GetCharCount();
// Treat a char count of -1 (error) as 0 (an empty page), since
// other pages might have valid content.
- const uint32_t char_count = std::max<uint32_t>(raw_char_count, 0);
+ const uint32_t char_count =
+ raw_char_count < 0 ? 0 : static_cast<uint32_t>(raw_char_count);
uint32_t char_index = 0;
while (char_index < char_count) {
AccessibilityTextRunInfo text_run = GetTextRunInfoAt(char_index).value();