Resolve unsafe buffer issues in CPDF_TextObject
Bug: pdfium:2155
Change-Id: Ie8d2d8bf8be8303f3489362845384ee6d17aabe9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/118953
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index d6257a3..58f2e36 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -1244,24 +1244,26 @@
->GetShading(std::move(pPattern), m_pCurStates->parent_matrix());
}
-void CPDF_StreamContentParser::AddTextObject(const ByteString* pStrs,
- float fInitKerning,
- const std::vector<float>& kernings,
- size_t nSegs) {
+void CPDF_StreamContentParser::AddTextObject(
+ pdfium::span<const ByteString> strings,
+ pdfium::span<const float> kernings,
+ float initial_kerning) {
RetainPtr<CPDF_Font> pFont = m_pCurStates->text_state().GetFont();
- if (!pFont)
+ if (!pFont) {
return;
-
- if (fInitKerning != 0) {
- if (pFont->IsVertWriting())
- m_pCurStates->IncrementTextPositionY(-GetVerticalTextSize(fInitKerning));
- else
- m_pCurStates->IncrementTextPositionX(
- -GetHorizontalTextSize(fInitKerning));
}
- if (nSegs == 0)
+ if (initial_kerning != 0) {
+ if (pFont->IsVertWriting()) {
+ m_pCurStates->IncrementTextPositionY(
+ -GetVerticalTextSize(initial_kerning));
+ } else {
+ m_pCurStates->IncrementTextPositionX(
+ -GetHorizontalTextSize(initial_kerning));
+ }
+ }
+ if (strings.empty()) {
return;
-
+ }
const TextRenderingMode text_mode =
pFont->IsType3Font() ? TextRenderingMode::MODE_FILL
: m_pCurStates->text_state().GetTextMode();
@@ -1278,7 +1280,7 @@
text_ctm[2] = ctm.b;
text_ctm[3] = ctm.d;
}
- pText->SetSegments(pStrs, kernings, nSegs);
+ pText->SetSegments(strings, kernings);
pText->SetPosition(m_mtContentToUser.Transform(
m_pCurStates->GetTransformedTextPosition()));
@@ -1290,13 +1292,13 @@
m_ClipTextList.push_back(pText->Clone());
m_pObjectHolder->AppendPageObject(std::move(pText));
}
- if (!kernings.empty() && kernings[nSegs - 1] != 0) {
+ if (!kernings.empty() && kernings.back() != 0) {
if (pFont->IsVertWriting())
m_pCurStates->IncrementTextPositionY(
- -GetVerticalTextSize(kernings[nSegs - 1]));
+ -GetVerticalTextSize(kernings.back()));
else
m_pCurStates->IncrementTextPositionX(
- -GetHorizontalTextSize(kernings[nSegs - 1]));
+ -GetHorizontalTextSize(kernings.back()));
}
}
@@ -1317,8 +1319,9 @@
void CPDF_StreamContentParser::Handle_ShowText() {
ByteString str = GetString(0);
- if (!str.IsEmpty())
- AddTextObject(&str, 0, std::vector<float>(), 1);
+ if (!str.IsEmpty()) {
+ AddTextObject(pdfium::span_from_ref(str), pdfium::span<float>(), 0.0f);
+ }
}
void CPDF_StreamContentParser::Handle_ShowText_Positioning() {
@@ -1364,7 +1367,8 @@
kernings[iSegment - 1] += num;
}
}
- AddTextObject(strs.data(), fInitKerning, kernings, iSegment);
+ AddTextObject(pdfium::make_span(strs).first(iSegment), kernings,
+ fInitKerning);
}
void CPDF_StreamContentParser::Handle_SetTextLeading() {
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h
index 6f8d8b9..1a9a0f3 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -105,10 +105,9 @@
// Makes a matrix from {GetNumber(5), ..., GetNumber(0)}.
CFX_Matrix GetMatrix() const;
void OnOperator(ByteStringView op);
- void AddTextObject(const ByteString* pStrs,
- float fInitKerning,
- const std::vector<float>& kernings,
- size_t nSegs);
+ void AddTextObject(pdfium::span<const ByteString> strings,
+ pdfium::span<const float> kernings,
+ float initial_kerning);
float GetHorizontalTextSize(float fKerning) const;
float GetVerticalTextSize(float fKerning) const;
diff --git a/core/fpdfapi/page/cpdf_textobject.cpp b/core/fpdfapi/page/cpdf_textobject.cpp
index 4fb1b5f..f552f40 100644
--- a/core/fpdfapi/page/cpdf_textobject.cpp
+++ b/core/fpdfapi/page/cpdf_textobject.cpp
@@ -4,11 +4,6 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
#include "core/fpdfapi/page/cpdf_textobject.h"
#include <algorithm>
@@ -18,6 +13,7 @@
#include "core/fxcrt/check.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/span.h"
+#include "core/fxcrt/span_util.h"
#define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF)
@@ -198,23 +194,23 @@
CalcPositionDataInternal(GetFont());
}
-void CPDF_TextObject::SetSegments(const ByteString* pStrs,
- const std::vector<float>& kernings,
- size_t nSegs) {
+void CPDF_TextObject::SetSegments(pdfium::span<const ByteString> strings,
+ pdfium::span<const float> kernings) {
+ size_t nSegs = strings.size();
CHECK(nSegs);
m_CharCodes.clear();
m_CharPos.clear();
RetainPtr<CPDF_Font> pFont = GetFont();
size_t nChars = nSegs - 1;
- for (size_t i = 0; i < nSegs; ++i)
- nChars += pFont->CountChar(pStrs[i].AsStringView());
-
+ for (const auto& str : strings) {
+ nChars += pFont->CountChar(str.AsStringView());
+ }
CHECK(nChars);
m_CharCodes.resize(nChars);
m_CharPos.resize(nChars - 1);
size_t index = 0;
for (size_t i = 0; i < nSegs; ++i) {
- ByteStringView segment = pStrs[i].AsStringView();
+ ByteStringView segment = strings[i].AsStringView();
size_t offset = 0;
while (offset < segment.GetLength()) {
DCHECK(index < m_CharCodes.size());
@@ -228,7 +224,7 @@
}
void CPDF_TextObject::SetText(const ByteString& str) {
- SetSegments(&str, std::vector<float>(), 1);
+ SetSegments(pdfium::span_from_ref(str), pdfium::span<float>());
CalcPositionDataInternal(GetFont());
SetDirty(true);
}
diff --git a/core/fpdfapi/page/cpdf_textobject.h b/core/fpdfapi/page/cpdf_textobject.h
index 4a936bc..374bc8e 100644
--- a/core/fpdfapi/page/cpdf_textobject.h
+++ b/core/fpdfapi/page/cpdf_textobject.h
@@ -17,6 +17,7 @@
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/span.h"
class CPDF_TextObject final : public CPDF_PageObject {
public:
@@ -70,9 +71,9 @@
// Caller is expected to call SetDirty(true) when done changing the object.
void SetTextMatrix(const CFX_Matrix& matrix);
- void SetSegments(const ByteString* pStrs,
- const std::vector<float>& kernings,
- size_t nSegs);
+ void SetSegments(pdfium::span<const ByteString> strings,
+ pdfium::span<const float> kernings);
+
CFX_PointF CalcPositionData(float horz_scale);
private: