diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-01-30 19:12:10 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-01-30 19:12:10 +0000 |
commit | aa1c7873c39964d063c89c14815e3fc566bbd896 (patch) | |
tree | 257726f71b9318d51587a9ed0d414e7acbdb0b46 /core | |
parent | 8cdea72a82aae5e07aa92e9886dbbe635eb8b7cc (diff) | |
download | pdfium-aa1c7873c39964d063c89c14815e3fc566bbd896.tar.xz |
Guard usages of tellp(). It may return -1 in error cases.
Change-Id: I064ddcad8671b9ade2c02142a6c2c2983846e3a9
Reviewed-on: https://pdfium-review.googlesource.com/24650
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/page/cpdf_streamparser.cpp | 9 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_stream.cpp | 10 | ||||
-rw-r--r-- | core/fxge/win32/cfx_psrenderer.cpp | 26 | ||||
-rw-r--r-- | core/fxge/win32/cfx_psrenderer.h | 1 | ||||
-rw-r--r-- | core/fxge/win32/fx_win32_gdipext.cpp | 6 |
5 files changed, 41 insertions, 11 deletions
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp index 2c7e0256f5..71c8c8d29a 100644 --- a/core/fpdfapi/page/cpdf_streamparser.cpp +++ b/core/fpdfapi/page/cpdf_streamparser.cpp @@ -478,6 +478,9 @@ ByteString CPDF_StreamParser::ReadString() { case 0: if (ch == ')') { if (parlevel == 0) { + if (buf.tellp() <= 0) + return ByteString(); + return ByteString( buf.str().c_str(), std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength)); @@ -557,6 +560,9 @@ ByteString CPDF_StreamParser::ReadString() { if (PositionIsInBounds()) ++m_Pos; + if (buf.tellp() <= 0) + return ByteString(); + return ByteString( buf.str().c_str(), std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength)); @@ -590,6 +596,9 @@ ByteString CPDF_StreamParser::ReadHexString() { if (!bFirst) buf << static_cast<char>(code); + if (buf.tellp() <= 0) + return ByteString(); + return ByteString( buf.str().c_str(), std::min(static_cast<size_t>(buf.tellp()), kMaxStringLength)); diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index 074e747a78..5ff748469b 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp @@ -100,6 +100,11 @@ void CPDF_Stream::SetDataAndRemoveFilter(const uint8_t* pData, uint32_t size) { } void CPDF_Stream::SetDataAndRemoveFilter(std::ostringstream* stream) { + if (stream->tellp() <= 0) { + SetDataAndRemoveFilter(nullptr, 0); + return; + } + SetDataAndRemoveFilter( reinterpret_cast<const uint8_t*>(stream->str().c_str()), stream->tellp()); } @@ -125,6 +130,11 @@ void CPDF_Stream::SetData(std::unique_ptr<uint8_t, FxFreeDeleter> pData, } void CPDF_Stream::SetData(std::ostringstream* stream) { + if (stream->tellp() <= 0) { + SetData(nullptr, 0); + return; + } + SetData(reinterpret_cast<const uint8_t*>(stream->str().c_str()), stream->tellp()); } diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp index 417a1d7b85..b79de57db2 100644 --- a/core/fxge/win32/cfx_psrenderer.cpp +++ b/core/fxge/win32/cfx_psrenderer.cpp @@ -206,7 +206,7 @@ void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, } } } - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); } void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData, @@ -239,7 +239,7 @@ void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData, buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " " << pObject2Device->c << " " << pObject2Device->d << " " << pObject2Device->e << " " << pObject2Device->f << "]cm "; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); OutputPath(pPathData, nullptr); CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, @@ -272,7 +272,7 @@ bool CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData, buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " " << pObject2Device->c << " " << pObject2Device->d << " " << pObject2Device->e << " " << pObject2Device->f << "]cm "; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); } } @@ -333,8 +333,7 @@ void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) { } m_CurGraphState.Copy(*pGraphState); m_bGraphStateSet = true; - if (buf.tellp()) - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); } bool CFX_PSRenderer::SetDIBits(const RetainPtr<CFX_DIBSource>& pSource, @@ -418,7 +417,7 @@ bool CFX_PSRenderer::DrawDIBits(const RetainPtr<CFX_DIBSource>& pSource, else buf << "false 1 colorimage\n"; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); WritePSBinary(output_buf.get(), output_size); output_buf.release(); } else { @@ -496,7 +495,7 @@ bool CFX_PSRenderer::DrawDIBits(const RetainPtr<CFX_DIBSource>& pSource, buf << "false " << bpp; buf << " colorimage\n"; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); WritePSBinary(output_buf, output_size); FX_Free(output_buf); @@ -522,7 +521,7 @@ void CFX_PSRenderer::SetColor(uint32_t color) { m_bColorSet = true; m_LastColor = color; } - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); } } @@ -569,7 +568,7 @@ void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, "currentdict end\n"; buf << "/X" << static_cast<uint32_t>(m_PSFontList.size() - 1) << " exch definefont pop\n"; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); buf.str(""); } @@ -631,7 +630,7 @@ void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, buf << "f}bind def end\n"; buf << "/X" << *ps_fontnum << " Ff/Encoding get " << glyphindex << "/" << glyphindex << " put\n"; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); } bool CFX_PSRenderer::DrawText(int nChars, @@ -676,7 +675,7 @@ bool CFX_PSRenderer::DrawText(int nChars, buf << hex.AsStringView() << "Tj\n"; } buf << "Q\n"; - m_pStream->WriteBlock(buf.str().c_str(), buf.tellp()); + WriteToStream(&buf); pCache->ReleaseCachedFace(pFont); return true; } @@ -693,3 +692,8 @@ void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) { m_pStream->WriteBlock(data, len); } } + +void CFX_PSRenderer::WriteToStream(std::ostringstream* stringStream) { + if (stringStream->tellp() > 0) + m_pStream->WriteBlock(stringStream->str().c_str(), stringStream->tellp()); +} diff --git a/core/fxge/win32/cfx_psrenderer.h b/core/fxge/win32/cfx_psrenderer.h index 33829ead98..4116dd4a51 100644 --- a/core/fxge/win32/cfx_psrenderer.h +++ b/core/fxge/win32/cfx_psrenderer.h @@ -85,6 +85,7 @@ class CFX_PSRenderer { int* ps_fontnum, int* ps_glyphindex); void WritePSBinary(const uint8_t* data, int len); + void WriteToStream(std::ostringstream* stringStream); RetainPtr<IFX_WriteStream> m_pStream; int m_PSLevel; diff --git a/core/fxge/win32/fx_win32_gdipext.cpp b/core/fxge/win32/fx_win32_gdipext.cpp index 64c8ea7408..a83a4496fe 100644 --- a/core/fxge/win32/fx_win32_gdipext.cpp +++ b/core/fxge/win32/fx_win32_gdipext.cpp @@ -952,6 +952,8 @@ class GpStream final : public IStream { start = m_ReadPos; break; case STREAM_SEEK_END: + if (m_InterStream.tellp() < 0) + return STG_E_SEEKERROR; start = m_InterStream.tellp(); break; default: @@ -973,6 +975,10 @@ class GpStream final : public IStream { return STG_E_INVALIDFUNCTION; ZeroMemory(pStatstg, sizeof(STATSTG)); + + if (m_InterStream.tellp() < 0) + return STG_E_SEEKERROR; + pStatstg->cbSize.QuadPart = m_InterStream.tellp(); return S_OK; } |