Re-work string template constructors
Allow better implicit conversions from spans.
-- avoid some confusion when using results of binary buffers
between const spans (which are ok) and non-const (not ok) by
forcing all existing callers into the const form of GetSpan().
-- add GetMutableSpan() for a few places where needed.
-- preserve property that strings created from empty vectors get
empty data pointers (makes null-checks faster by a tad) and
passes existing tests.
Change-Id: I3557224c6ad0251c26217febd8d28af74efedea8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98072
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index bb49ab9..7965769 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -147,8 +147,9 @@
if (m_Cipher == Cipher::kRC4) {
size_t old_size = dest_buf.GetSize();
dest_buf.AppendBlock(source.data(), source.size());
- CRYPT_ArcFourCrypt(static_cast<CRYPT_rc4_context*>(context),
- dest_buf.GetSpan().subspan(old_size, source.size()));
+ CRYPT_ArcFourCrypt(
+ static_cast<CRYPT_rc4_context*>(context),
+ dest_buf.GetMutableSpan().subspan(old_size, source.size()));
return true;
}
AESCryptContext* pContext = static_cast<AESCryptContext*>(context);
diff --git a/core/fxcrt/binary_buffer.cpp b/core/fxcrt/binary_buffer.cpp
index d714d2d..e527e26 100644
--- a/core/fxcrt/binary_buffer.cpp
+++ b/core/fxcrt/binary_buffer.cpp
@@ -47,7 +47,7 @@
m_DataSize -= count;
}
-pdfium::span<uint8_t> BinaryBuffer::GetSpan() {
+pdfium::span<uint8_t> BinaryBuffer::GetMutableSpan() {
return {m_buffer.data(), GetSize()};
}
diff --git a/core/fxcrt/binary_buffer.h b/core/fxcrt/binary_buffer.h
index 478df0d..e23812b 100644
--- a/core/fxcrt/binary_buffer.h
+++ b/core/fxcrt/binary_buffer.h
@@ -28,7 +28,7 @@
BinaryBuffer& operator=(const BinaryBuffer& that) = delete;
- pdfium::span<uint8_t> GetSpan();
+ pdfium::span<uint8_t> GetMutableSpan();
pdfium::span<const uint8_t> GetSpan() const;
bool IsEmpty() const { return GetLength() == 0; }
size_t GetSize() const { return m_DataSize; } // In bytes.
diff --git a/core/fxcrt/string_view_template.h b/core/fxcrt/string_view_template.h
index d2f0d41..28af5b1 100644
--- a/core/fxcrt/string_view_template.h
+++ b/core/fxcrt/string_view_template.h
@@ -12,7 +12,6 @@
#include <algorithm>
#include <iterator>
#include <type_traits>
-#include <vector>
#include "core/fxcrt/fx_system.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -49,28 +48,26 @@
: m_Span(reinterpret_cast<const UnsignedType*>(ptr),
ptr ? FXSYS_len(ptr) : 0) {}
- constexpr StringViewTemplate(const CharType* ptr, size_t len) noexcept
- : m_Span(reinterpret_cast<const UnsignedType*>(ptr), len) {}
+ constexpr StringViewTemplate(const CharType* ptr, size_t size) noexcept
+ : m_Span(reinterpret_cast<const UnsignedType*>(ptr), size) {}
+
+ template <typename E = typename std::enable_if<
+ !std::is_same<UnsignedType, CharType>::value>::type>
+ constexpr StringViewTemplate(const UnsignedType* ptr, size_t size) noexcept
+ : m_Span(ptr, size) {}
explicit constexpr StringViewTemplate(
const pdfium::span<const CharType>& other) noexcept
- : m_Span(reinterpret_cast<const UnsignedType*>(other.data()),
+ : m_Span(other.size()
+ ? reinterpret_cast<const UnsignedType*>(other.data())
+ : nullptr,
other.size()) {}
- template <typename U = UnsignedType>
+ template <typename E = typename std::enable_if<
+ !std::is_same<UnsignedType, CharType>::value>::type>
constexpr StringViewTemplate(
- const UnsignedType* ptr,
- size_t size,
- typename std::enable_if<!std::is_same<U, CharType>::value>::type* =
- 0) noexcept
- : m_Span(ptr, size) {}
-
- template <typename U = UnsignedType>
- StringViewTemplate(
- const pdfium::span<U> other,
- typename std::enable_if<!std::is_same<U, CharType>::value>::type* =
- 0) noexcept
- : m_Span(other) {}
+ const pdfium::span<const UnsignedType>& other) noexcept
+ : m_Span(other.size() ? other.data() : nullptr, other.size()) {}
// Deliberately implicit to avoid calling on every char literal.
// |ch| must be an lvalue that outlives the StringViewTemplate.
@@ -78,12 +75,6 @@
constexpr StringViewTemplate(const CharType& ch) noexcept
: m_Span(reinterpret_cast<const UnsignedType*>(&ch), 1) {}
- // Any changes to |vec| invalidate the string.
- template <typename AllocType>
- explicit StringViewTemplate(
- const std::vector<UnsignedType, AllocType>& vec) noexcept
- : m_Span(!vec.empty() ? vec.data() : nullptr, vec.size()) {}
-
StringViewTemplate& operator=(const CharType* src) {
m_Span = pdfium::span<const UnsignedType>(
reinterpret_cast<const UnsignedType*>(src), src ? FXSYS_len(src) : 0);
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index 1898703..1b8ecd8 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -389,7 +389,7 @@
sFile.AppendBlock(&dwSize, sizeof(uint32_t));
sFile.AppendSpan(sData.GetSpan());
- CRYPT_ArcFourCryptBlock(sFile.GetSpan(), kRC4KEY);
+ CRYPT_ArcFourCryptBlock(sFile.GetMutableSpan(), kRC4KEY);
return m_pDelegate->StoreBuffer(sFile.GetSpan());
}