Change CPDF_Stream to store memory-based data in a DataVector. Use DataVector instead of std::unique_ptr so there's just a single container to pass around, instead of a container and a size variable. Remove TakeDataInternal() and either merge its code into TakeData(), or move it to SetLengthInDict(). Bug: pdfium:1872 Change-Id: Ia3a7cd08a5419283e47ff89fbfa01a97842f39dc Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/96213 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index 9ecae3a..4f7a809 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -36,13 +36,6 @@ } // namespace -CPDF_Stream::OwnedData::OwnedData( - std::unique_ptr<uint8_t, FxFreeDeleter> buffer, - size_t size) - : buffer(std::move(buffer)), size(size) {} - -CPDF_Stream::OwnedData::~OwnedData() = default; - CPDF_Stream::CPDF_Stream() = default; CPDF_Stream::CPDF_Stream(pdfium::span<const uint8_t> pData, @@ -53,16 +46,18 @@ CPDF_Stream::CPDF_Stream(DataVector<uint8_t> pData, RetainPtr<CPDF_Dictionary> pDict) - : dict_(std::move(pDict)) { - // TODO(crbug.com/pdfium/1872): Avoid copying. - SetData(pData); + : data_(std::move(pData)), dict_(std::move(pDict)) { + SetLengthInDict(pdfium::base::checked_cast<int>( + absl::get<DataVector<uint8_t>>(data_).size())); } CPDF_Stream::CPDF_Stream(std::unique_ptr<uint8_t, FxFreeDeleter> pData, size_t size, RetainPtr<CPDF_Dictionary> pDict) - : dict_(std::move(pDict)) { - TakeDataInternal(std::move(pData), size); + : data_(DataVector<uint8_t>(pData.get(), pData.get() + size)), + dict_(std::move(pDict)) { + SetLengthInDict(pdfium::base::checked_cast<int>( + absl::get<DataVector<uint8_t>>(data_).size())); } CPDF_Stream::~CPDF_Stream() { @@ -93,8 +88,7 @@ RetainPtr<CPDF_Dictionary> pDict) { data_ = pFile; dict_ = std::move(pDict); - dict_->SetNewFor<CPDF_Number>( - "Length", pdfium::base::checked_cast<int>(pFile->GetSize())); + SetLengthInDict(pdfium::base::checked_cast<int>(pFile->GetSize())); } RetainPtr<CPDF_Object> CPDF_Stream::Clone() const { @@ -138,28 +132,16 @@ } void CPDF_Stream::SetData(pdfium::span<const uint8_t> pData) { - std::unique_ptr<uint8_t, FxFreeDeleter> data_copy; - if (!pData.empty()) { - data_copy.reset(FX_AllocUninit(uint8_t, pData.size())); - auto copy_span = pdfium::make_span(data_copy.get(), pData.size()); - fxcrt::spancpy(copy_span, pData); - } - TakeDataInternal(std::move(data_copy), pData.size()); + DataVector<uint8_t> data_copy(pData.begin(), pData.end()); + TakeData(std::move(data_copy)); } void CPDF_Stream::TakeData(DataVector<uint8_t> data) { - // TODO(crbug.com/pdfium/1872): Avoid copying. - SetData(data); -} - -void CPDF_Stream::TakeDataInternal( - std::unique_ptr<uint8_t, FxFreeDeleter> pData, - size_t size) { - data_.emplace<OwnedData>(std::move(pData), size); + const size_t size = data.size(); + data_ = std::move(data); if (!dict_) dict_ = pdfium::MakeRetain<CPDF_Dictionary>(); - dict_->SetNewFor<CPDF_Number>("Length", - pdfium::base::checked_cast<int>(size)); + SetLengthInDict(pdfium::base::checked_cast<int>(size)); } void CPDF_Stream::SetDataFromStringstream(fxcrt::ostringstream* stream) { @@ -220,13 +202,16 @@ absl::get<RetainPtr<IFX_SeekableReadStream>>(data_)->GetSize()); } if (IsMemoryBased()) - return absl::get<OwnedData>(data_).size; + return absl::get<DataVector<uint8_t>>(data_).size(); DCHECK(IsUninitialized()); return 0; } pdfium::span<const uint8_t> CPDF_Stream::GetInMemoryRawData() const { DCHECK(IsMemoryBased()); - const auto& data = absl::get<OwnedData>(data_); - return pdfium::make_span(data.buffer.get(), data.size); + return absl::get<DataVector<uint8_t>>(data_); +} + +void CPDF_Stream::SetLengthInDict(int length) { + dict_->SetNewFor<CPDF_Number>("Length", length); }
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h index 783c617..812d4ae 100644 --- a/core/fpdfapi/parser/cpdf_stream.h +++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -67,15 +67,6 @@ bool HasFilter() const; private: - // TODO(crbug.com/pdfium/1872): Replace with DataVector. - struct OwnedData { - OwnedData(std::unique_ptr<uint8_t, FxFreeDeleter> buffer, size_t size); - ~OwnedData(); - - std::unique_ptr<uint8_t, FxFreeDeleter> buffer; - size_t size; - }; - CPDF_Stream(); CPDF_Stream(pdfium::span<const uint8_t> pData, RetainPtr<CPDF_Dictionary> pDict); @@ -90,11 +81,11 @@ bool bDirect, std::set<const CPDF_Object*>* pVisited) const override; - // TODO(crbug.com/pdfium/1872): Replace with vector version. - void TakeDataInternal(std::unique_ptr<uint8_t, FxFreeDeleter> pData, - size_t size); + void SetLengthInDict(int length); - absl::variant<absl::monostate, RetainPtr<IFX_SeekableReadStream>, OwnedData> + absl::variant<absl::monostate, + RetainPtr<IFX_SeekableReadStream>, + DataVector<uint8_t>> data_; RetainPtr<CPDF_Dictionary> dict_; };