Introduce CFX_ReadOnlyVectorStream.
Introduce a class that can take ownership of a DataVector<uint8_t> and
expose the data as a read-only stream. Use this new class where
possible. In cxfa_node.cpp, this make object lifetime management easier.
Change-Id: I4b6d4a4bab40465fc035e86bf3a14877241299cb
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/96757
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp b/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp
index 3c01139..ad6c017 100644
--- a/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp
@@ -10,6 +10,7 @@
#include <utility>
#include "core/fxcrt/cfx_read_only_span_stream.h"
+#include "core/fxcrt/cfx_read_only_vector_stream.h"
#include "core/fxcrt/data_vector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/invalid_seekable_read_stream.h"
@@ -68,7 +69,8 @@
TEST(ReadValidatorTest, UnavailableData) {
DataVector<uint8_t> test_data(kTestDataSize);
- auto file = pdfium::MakeRetain<CFX_ReadOnlySpanStream>(test_data);
+ auto file =
+ pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(test_data));
MockFileAvail file_avail;
auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(file, &file_avail);
@@ -91,7 +93,8 @@
TEST(ReadValidatorTest, UnavailableDataWithHints) {
DataVector<uint8_t> test_data(kTestDataSize);
- auto file = pdfium::MakeRetain<CFX_ReadOnlySpanStream>(test_data);
+ auto file =
+ pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(test_data));
MockFileAvail file_avail;
auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(file, &file_avail);
@@ -146,7 +149,8 @@
TEST(ReadValidatorTest, IntOverflow) {
DataVector<uint8_t> test_data(kTestDataSize);
- auto file = pdfium::MakeRetain<CFX_ReadOnlySpanStream>(test_data);
+ auto file =
+ pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(test_data));
MockFileAvail file_avail;
auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(file, &file_avail);
@@ -244,7 +248,8 @@
TEST(ReadValidatorTest, CheckDataRangeAndRequestIfUnavailable) {
DataVector<uint8_t> test_data(kTestDataSize);
- auto file = pdfium::MakeRetain<CFX_ReadOnlySpanStream>(test_data);
+ auto file =
+ pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(test_data));
MockFileAvail file_avail;
auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(file, &file_avail);
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 24dadb4..aaa2353 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -27,6 +27,8 @@
"cfx_read_only_memory_stream.h",
"cfx_read_only_span_stream.cpp",
"cfx_read_only_span_stream.h",
+ "cfx_read_only_vector_stream.cpp",
+ "cfx_read_only_vector_stream.h",
"cfx_seekablestreamproxy.cpp",
"cfx_seekablestreamproxy.h",
"cfx_timer.cpp",
diff --git a/core/fxcrt/cfx_read_only_vector_stream.cpp b/core/fxcrt/cfx_read_only_vector_stream.cpp
new file mode 100644
index 0000000..0e6488b
--- /dev/null
+++ b/core/fxcrt/cfx_read_only_vector_stream.cpp
@@ -0,0 +1,26 @@
+// Copyright 2022 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcrt/cfx_read_only_vector_stream.h"
+
+#include <utility>
+
+#include "core/fxcrt/cfx_read_only_span_stream.h"
+#include "third_party/base/span.h"
+
+CFX_ReadOnlyVectorStream::CFX_ReadOnlyVectorStream(DataVector<uint8_t> data)
+ : data_(std::move(data)),
+ stream_(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(data_)) {}
+
+CFX_ReadOnlyVectorStream::~CFX_ReadOnlyVectorStream() = default;
+
+FX_FILESIZE CFX_ReadOnlyVectorStream::GetSize() {
+ return stream_->GetSize();
+}
+
+bool CFX_ReadOnlyVectorStream::ReadBlockAtOffset(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ return stream_->ReadBlockAtOffset(buffer, offset, size);
+}
diff --git a/core/fxcrt/cfx_read_only_vector_stream.h b/core/fxcrt/cfx_read_only_vector_stream.h
new file mode 100644
index 0000000..ac93dca
--- /dev/null
+++ b/core/fxcrt/cfx_read_only_vector_stream.h
@@ -0,0 +1,34 @@
+// Copyright 2022 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXCRT_CFX_READ_ONLY_VECTOR_STREAM_H_
+#define CORE_FXCRT_CFX_READ_ONLY_VECTOR_STREAM_H_
+
+#include <stdint.h>
+
+#include "core/fxcrt/data_vector.h"
+#include "core/fxcrt/fx_stream.h"
+#include "core/fxcrt/retain_ptr.h"
+
+class CFX_ReadOnlySpanStream;
+
+class CFX_ReadOnlyVectorStream final : public IFX_SeekableReadStream {
+ public:
+ CONSTRUCT_VIA_MAKE_RETAIN;
+
+ // IFX_SeekableReadStream:
+ FX_FILESIZE GetSize() override;
+ bool ReadBlockAtOffset(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) override;
+
+ private:
+ explicit CFX_ReadOnlyVectorStream(DataVector<uint8_t> data);
+ ~CFX_ReadOnlyVectorStream() override;
+
+ const DataVector<uint8_t> data_;
+ const RetainPtr<CFX_ReadOnlySpanStream> stream_;
+};
+
+#endif // CORE_FXCRT_CFX_READ_ONLY_VECTOR_STREAM_H_
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 08bf3bf..c190b1b 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -18,6 +18,7 @@
#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/cfx_read_only_span_stream.h"
+#include "core/fxcrt/cfx_read_only_vector_stream.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
@@ -481,17 +482,15 @@
FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
ByteString bsData; // Must outlive |pImageFileRead|.
- // Must outlive |pImageFileRead|.
- DataVector<uint8_t> buffer;
-
RetainPtr<IFX_SeekableReadStream> pImageFileRead;
if (wsImage.GetLength() > 0) {
XFA_AttributeValue iEncoding = pImage->GetTransferEncoding();
if (iEncoding == XFA_AttributeValue::Base64) {
- bsData = wsImage.ToUTF8();
- buffer = XFA_Base64Decode(bsData);
- if (!buffer.empty())
- pImageFileRead = pdfium::MakeRetain<CFX_ReadOnlySpanStream>(buffer);
+ DataVector<uint8_t> buffer = XFA_Base64Decode(wsImage.ToUTF8());
+ if (!buffer.empty()) {
+ pImageFileRead =
+ pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(buffer));
+ }
} else {
bsData = wsImage.ToDefANSI();
pImageFileRead =