diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-09-28 17:58:18 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-09-28 15:10:48 +0000 |
commit | 0ec10f94ae0ec1927c4a33cd69eac0a5fbdcbd52 (patch) | |
tree | 57463da5d9d6fcf2aa310e0e9153078123edd977 /core/fpdfapi/parser/cpdf_syntax_parser.cpp | |
parent | 6e376202fca5c4f77645ba0eeee56ef3c44615a3 (diff) | |
download | pdfium-0ec10f94ae0ec1927c4a33cd69eac0a5fbdcbd52.tar.xz |
Fix infinite loop on form availability check.
The problem was, that the CPDF_SyntaxParser read last block
not from requested position. In this case It move down
requested position to fill whole buffer. As result this additional
data was not requested by DownloadHints.
To fix this allow resize data buffer in CPDF_SyntaxParser, to store
more small block, and always read from requsted position.
Also add reading check into CPDF_Parser::LoadLinearizedMainXRefTable to
prevent infinite loops.
Change-Id: I14d3f4457393025dca390aa3ceaa940716463534
Reviewed-on: https://pdfium-review.googlesource.com/11891
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_syntax_parser.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.cpp | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index 96a863e661..ac401b351d 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -46,12 +46,9 @@ CPDF_SyntaxParser::CPDF_SyntaxParser() CPDF_SyntaxParser::CPDF_SyntaxParser(const WeakPtr<ByteStringPool>& pPool) : m_MetadataObjnum(0), m_pFileAccess(nullptr), - m_pFileBuf(nullptr), - m_BufSize(CPDF_ModuleMgr::kFileBufSize), m_pPool(pPool) {} CPDF_SyntaxParser::~CPDF_SyntaxParser() { - FX_Free(m_pFileBuf); } bool CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { @@ -60,17 +57,20 @@ bool CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { return GetNextChar(ch); } -bool CPDF_SyntaxParser::ReadChar(FX_FILESIZE read_pos, uint32_t read_size) { - if (static_cast<FX_FILESIZE>(read_pos + read_size) > m_FileLen) { - if (m_FileLen < static_cast<FX_FILESIZE>(read_size)) { - read_pos = 0; - read_size = static_cast<uint32_t>(m_FileLen); - } else { - read_pos = m_FileLen - read_size; - } - } - if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) +bool CPDF_SyntaxParser::ReadBlockAt(FX_FILESIZE read_pos) { + if (read_pos >= m_FileLen) return false; + size_t read_size = CPDF_ModuleMgr::kFileBufSize; + FX_SAFE_FILESIZE safe_end = read_pos; + safe_end += read_size; + if (!safe_end.IsValid() || safe_end.ValueOrDie() > m_FileLen) + read_size = m_FileLen - read_pos; + + m_pFileBuf.resize(read_size); + if (!m_pFileAccess->ReadBlock(m_pFileBuf.data(), read_pos, read_size)) { + m_pFileBuf.clear(); + return false; + } m_BufOffset = read_pos; return true; @@ -81,13 +81,9 @@ bool CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { if (pos >= m_FileLen) return false; - if (CheckPosition(pos)) { - FX_FILESIZE read_pos = pos; - uint32_t read_size = m_BufSize; - read_size = std::min(read_size, static_cast<uint32_t>(m_FileLen)); - if (!ReadChar(read_pos, read_size)) - return false; - } + if (!IsPositionRead(pos) && !ReadBlockAt(pos)) + return false; + ch = m_pFileBuf[pos - m_BufOffset]; m_Pos++; return true; @@ -98,14 +94,11 @@ bool CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t* ch) { if (pos >= m_FileLen) return false; - if (CheckPosition(pos)) { - FX_FILESIZE read_pos; - if (pos < static_cast<FX_FILESIZE>(m_BufSize)) - read_pos = 0; - else - read_pos = pos - m_BufSize + 1; - uint32_t read_size = m_BufSize; - if (!ReadChar(read_pos, read_size)) + if (!IsPositionRead(pos)) { + FX_FILESIZE block_start = 0; + if (pos >= CPDF_ModuleMgr::kFileBufSize) + block_start = pos - CPDF_ModuleMgr::kFileBufSize + 1; + if (!ReadBlockAt(block_start) || !IsPositionRead(pos)) return false; } *ch = m_pFileBuf[pos - m_BufOffset]; @@ -735,15 +728,12 @@ void CPDF_SyntaxParser::InitParserWithValidator( const RetainPtr<CPDF_ReadValidator>& validator, uint32_t HeaderOffset) { ASSERT(validator); - FX_Free(m_pFileBuf); - m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); + m_pFileBuf.clear(); m_HeaderOffset = HeaderOffset; m_FileLen = validator->GetSize(); m_Pos = 0; m_pFileAccess = validator; m_BufOffset = 0; - validator->ReadBlock(m_pFileBuf, 0, - std::min(m_BufSize, static_cast<uint32_t>(m_FileLen))); } uint32_t CPDF_SyntaxParser::GetDirectNum() { @@ -852,3 +842,8 @@ void CPDF_SyntaxParser::SetEncrypt( RetainPtr<IFX_SeekableReadStream> CPDF_SyntaxParser::GetFileAccess() const { return m_pFileAccess; } + +bool CPDF_SyntaxParser::IsPositionRead(FX_FILESIZE pos) const { + return m_BufOffset <= pos && + pos < static_cast<FX_FILESIZE>(m_BufOffset + m_pFileBuf.size()); +} |