From aa1c7873c39964d063c89c14815e3fc566bbd896 Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 30 Jan 2018 19:12:10 +0000 Subject: 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 Reviewed-by: dsinclair --- core/fpdfapi/page/cpdf_streamparser.cpp | 9 +++++++++ core/fpdfapi/parser/cpdf_stream.cpp | 10 ++++++++++ core/fxge/win32/cfx_psrenderer.cpp | 26 +++++++++++++++----------- core/fxge/win32/cfx_psrenderer.h | 1 + core/fxge/win32/fx_win32_gdipext.cpp | 6 ++++++ fpdfsdk/cpdfsdk_interform.cpp | 2 +- 6 files changed, 42 insertions(+), 12 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(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(buf.tellp()), kMaxStringLength)); @@ -590,6 +596,9 @@ ByteString CPDF_StreamParser::ReadHexString() { if (!bFirst) buf << static_cast(code); + if (buf.tellp() <= 0) + return ByteString(); + return ByteString( buf.str().c_str(), std::min(static_cast(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(stream->str().c_str()), stream->tellp()); } @@ -125,6 +130,11 @@ void CPDF_Stream::SetData(std::unique_ptr pData, } void CPDF_Stream::SetData(std::ostringstream* stream) { + if (stream->tellp() <= 0) { + SetData(nullptr, 0); + return; + } + SetData(reinterpret_cast(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& pSource, @@ -418,7 +417,7 @@ bool CFX_PSRenderer::DrawDIBits(const RetainPtr& 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& 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(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 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; } diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp index 03a782b15b..3b76dca682 100644 --- a/fpdfsdk/cpdfsdk_interform.cpp +++ b/fpdfsdk/cpdfsdk_interform.cpp @@ -530,7 +530,7 @@ bool CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, size_t& nBufSize) { } nBufSize = fdfEncodedData.tellp(); - if (nBufSize == 0) + if (nBufSize <= 0) return false; pBuf = FX_Alloc(uint8_t, nBufSize); -- cgit v1.2.3