summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2017-08-16 09:53:43 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-08-16 18:39:43 +0000
commitcd04b727f0b182f4ca39bb5b9198ba2f6389e05d (patch)
treeca2f4a25f94ede66fe384a187899a7a458b7b9e1
parent63b2fc7e0248d2112935775f52027a018b9aa737 (diff)
downloadpdfium-cd04b727f0b182f4ca39bb5b9198ba2f6389e05d.tar.xz
Fix potential OOM / integer overflow in CPDF_Parser.
The count passed into ParseAndAppendCrossRefSubsectionData() may be invalid. BUG=chromium:752796 Change-Id: Ic7bbfd16761d1df0855e6c77e4abc68823b12395 Reviewed-on: https://pdfium-review.googlesource.com/11130 Reviewed-by: Art Snake <art-snake@yandex-team.ru> Commit-Queue: Lei Zhang <thestig@chromium.org>
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index bf711bd972..34c59ed032 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -471,21 +471,40 @@ bool CPDF_Parser::ParseAndAppendCrossRefSubsectionData(
static constexpr int32_t kEntryConstSize = 20;
if (!out_objects) {
- m_pSyntax->SetPos(m_pSyntax->GetPos() + count * kEntryConstSize);
+ FX_SAFE_FILESIZE pos = count;
+ pos *= kEntryConstSize;
+ pos += m_pSyntax->GetPos();
+ if (!pos.IsValid())
+ return false;
+ m_pSyntax->SetPos(pos.ValueOrDie());
return true;
}
const size_t start_obj_index = out_objects->size();
- out_objects->resize(start_obj_index + count);
+ FX_SAFE_SIZE_T new_size = start_obj_index;
+ new_size += count;
+ if (!new_size.IsValid())
+ return false;
+
+ if (new_size.ValueOrDie() > kMaxXRefSize)
+ return false;
+
+ const size_t max_entries_in_file =
+ m_pSyntax->GetFileAccess()->GetSize() / kEntryConstSize;
+ if (new_size.ValueOrDie() > max_entries_in_file)
+ return false;
+
+ out_objects->resize(new_size.ValueOrDie());
std::vector<char> buf(1024 * kEntryConstSize + 1);
- buf[1024 * kEntryConstSize] = '\0';
+ buf.back() = '\0';
int32_t nBlocks = count / 1024 + 1;
for (int32_t block = 0; block < nBlocks; block++) {
int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
if (!m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()),
- block_size * kEntryConstSize))
+ block_size * kEntryConstSize)) {
return false;
+ }
for (int32_t i = 0; i < block_size; i++) {
CrossRefObjData& obj_data =