diff options
author | Lei Zhang <thestig@chromium.org> | 2017-08-16 09:53:43 -0700 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-08-16 18:39:43 +0000 |
commit | cd04b727f0b182f4ca39bb5b9198ba2f6389e05d (patch) | |
tree | ca2f4a25f94ede66fe384a187899a7a458b7b9e1 /core/fpdfapi/parser/cpdf_parser.cpp | |
parent | 63b2fc7e0248d2112935775f52027a018b9aa737 (diff) | |
download | pdfium-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>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_parser.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 27 |
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 = |