summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn2
-rw-r--r--core/fpdfapi/parser/cfdf_document.cpp4
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp17
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp10
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp29
-rw-r--r--core/fxcrt/cfx_memorystream.cpp199
-rw-r--r--core/fxcrt/cfx_memorystream.h56
-rw-r--r--core/fxcrt/cfx_seekablestreamproxy.cpp5
-rw-r--r--core/fxcrt/fx_stream.cpp232
-rw-r--r--core/fxcrt/fx_stream.h16
-rw-r--r--core/fxcrt/xml/cfx_saxreader_unittest.cpp10
-rw-r--r--fpdfsdk/fpdfsave.cpp12
-rw-r--r--testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc7
-rw-r--r--xfa/fgas/font/cfgas_fontmgr.cpp4
-rw-r--r--xfa/fxfa/cxfa_ffdoc.cpp6
-rw-r--r--xfa/fxfa/cxfa_ffwidget.cpp9
-rw-r--r--xfa/fxfa/parser/cxfa_dataexporter.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp4
18 files changed, 328 insertions, 298 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 135cbfbf80..ab221062ae 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -753,6 +753,8 @@ static_library("fxcrt") {
"core/fxcrt/cfx_bytestring.cpp",
"core/fxcrt/cfx_bytestring.h",
"core/fxcrt/cfx_maybe_owned.h",
+ "core/fxcrt/cfx_memorystream.cpp",
+ "core/fxcrt/cfx_memorystream.h",
"core/fxcrt/cfx_observable.h",
"core/fxcrt/cfx_retain_ptr.h",
"core/fxcrt/cfx_shared_copy_on_write.h",
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index 03cc655a0a..85e2f6ef04 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -13,6 +13,7 @@
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "third_party/base/ptr_util.h"
CFDF_Document::CFDF_Document()
@@ -39,7 +40,8 @@ std::unique_ptr<CFDF_Document> CFDF_Document::ParseFile(
std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory(uint8_t* pData,
uint32_t size) {
- return CFDF_Document::ParseFile(IFX_MemoryStream::Create(pData, size));
+ return CFDF_Document::ParseFile(
+ pdfium::MakeRetain<CFX_MemoryStream>(pData, size, false));
}
void CFDF_Document::ParseStream(
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index f99cb467e5..41a3f0dae2 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -21,6 +21,7 @@
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_safe_types.h"
#include "third_party/base/numerics/safe_conversions.h"
@@ -716,8 +717,8 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) {
if (m_pLinearized)
return true;
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(pData, (size_t)dwLen, false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ pData, static_cast<size_t>(dwLen), false);
int32_t offset = GetHeaderOffset(file);
if (offset == -1) {
m_docStatus = PDF_DATAAVAIL_ERROR;
@@ -756,8 +757,8 @@ bool CPDF_DataAvail::CheckEnd(DownloadHints* pHints) {
uint8_t buffer[1024];
m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(buffer, (size_t)dwSize, false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ buffer, static_cast<size_t>(dwSize), false);
m_syntaxParser.InitParser(file, 0);
m_syntaxParser.RestorePos(dwSize - 1);
@@ -804,8 +805,8 @@ int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints,
m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ pBuf, static_cast<size_t>(iSize), false);
m_parser.m_pSyntax->InitParser(file, 0);
bool bNumber;
@@ -1049,8 +1050,8 @@ bool CPDF_DataAvail::CheckTrailer(DownloadHints* pHints) {
if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
return false;
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ pBuf, static_cast<size_t>(iSize), false);
m_syntaxParser.InitParser(file, 0);
std::unique_ptr<CPDF_Object> pTrailer(
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index c18a183a33..86428ab9d7 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -22,6 +22,7 @@
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_safe_types.h"
#include "third_party/base/ptr_util.h"
@@ -1114,8 +1115,9 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
if (!pObjStream)
return nullptr;
- CFX_RetainPtr<IFX_MemoryStream> file = IFX_MemoryStream::Create(
- (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(pObjStream->GetData()),
+ static_cast<size_t>(pObjStream->GetSize()), false);
CPDF_SyntaxParser syntax;
syntax.InitParser(file, 0);
const int32_t offset = GetStreamFirst(pObjStream);
@@ -1194,8 +1196,8 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
int32_t offset = GetStreamFirst(pObjStream);
const uint8_t* pData = pObjStream->GetData();
uint32_t totalsize = pObjStream->GetSize();
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false);
+ auto file = pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(pData), static_cast<size_t>(totalsize), false);
CPDF_SyntaxParser syntax;
syntax.InitParser(file, 0);
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
index 5c7aa6054b..249276f29a 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
@@ -8,6 +8,7 @@
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_stream.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -18,7 +19,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Empty string.
uint8_t data[] = "";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 0, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 0, false), 0);
EXPECT_EQ("", parser.ReadHexString());
EXPECT_EQ(0, parser.SavePos());
}
@@ -27,7 +28,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Blank string.
uint8_t data[] = " ";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 2, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 2, false), 0);
EXPECT_EQ("", parser.ReadHexString());
EXPECT_EQ(2, parser.SavePos());
}
@@ -36,7 +37,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Skips unknown characters.
uint8_t data[] = "z12b";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0);
EXPECT_EQ("\x12\xb0", parser.ReadHexString());
EXPECT_EQ(4, parser.SavePos());
}
@@ -45,7 +46,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Skips unknown characters.
uint8_t data[] = "*<&*#$^&@1";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 10, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 10, false), 0);
EXPECT_EQ("\x10", parser.ReadHexString());
EXPECT_EQ(10, parser.SavePos());
}
@@ -54,7 +55,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Skips unknown characters.
uint8_t data[] = "\x80zab";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0);
EXPECT_EQ("\xab", parser.ReadHexString());
EXPECT_EQ(4, parser.SavePos());
}
@@ -63,7 +64,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Skips unknown characters.
uint8_t data[] = "\xffzab";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0);
EXPECT_EQ("\xab", parser.ReadHexString());
EXPECT_EQ(4, parser.SavePos());
}
@@ -72,7 +73,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Regular conversion.
uint8_t data[] = "1A2b>abcd";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 9, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 9, false), 0);
EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
EXPECT_EQ(5, parser.SavePos());
}
@@ -81,7 +82,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Position out of bounds.
uint8_t data[] = "12ab>";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 5, false), 0);
parser.RestorePos(5);
EXPECT_EQ("", parser.ReadHexString());
@@ -103,7 +104,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Missing ending >.
uint8_t data[] = "1A2b";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 4, false), 0);
EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
EXPECT_EQ(4, parser.SavePos());
}
@@ -112,7 +113,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Missing ending >.
uint8_t data[] = "12abz";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 5, false), 0);
EXPECT_EQ("\x12\xab", parser.ReadHexString());
EXPECT_EQ(5, parser.SavePos());
}
@@ -121,7 +122,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Uneven number of bytes.
uint8_t data[] = "1A2>asdf";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 8, false), 0);
EXPECT_EQ("\x1a\x20", parser.ReadHexString());
EXPECT_EQ(4, parser.SavePos());
}
@@ -130,7 +131,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Uneven number of bytes.
uint8_t data[] = "1A2zasdf";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 8, false), 0);
EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
EXPECT_EQ(8, parser.SavePos());
}
@@ -139,7 +140,7 @@ TEST(cpdf_syntax_parser, ReadHexString) {
// Just ending character.
uint8_t data[] = ">";
CPDF_SyntaxParser parser;
- parser.InitParser(IFX_MemoryStream::Create(data, 1, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 1, false), 0);
EXPECT_EQ("", parser.ReadHexString());
EXPECT_EQ(1, parser.SavePos());
}
@@ -149,7 +150,7 @@ TEST(cpdf_syntax_parser, GetInvalidReference) {
CPDF_SyntaxParser parser;
// Data with a reference with number CPDF_Object::kInvalidObjNum
uint8_t data[] = "4294967295 0 R";
- parser.InitParser(IFX_MemoryStream::Create(data, 14, false), 0);
+ parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 14, false), 0);
std::unique_ptr<CPDF_Object> ref =
parser.GetObject(nullptr, CPDF_Object::kInvalidObjNum, 0, false);
EXPECT_FALSE(ref);
diff --git a/core/fxcrt/cfx_memorystream.cpp b/core/fxcrt/cfx_memorystream.cpp
new file mode 100644
index 0000000000..345b381226
--- /dev/null
+++ b/core/fxcrt/cfx_memorystream.cpp
@@ -0,0 +1,199 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcrt/cfx_memorystream.h"
+
+#include <algorithm>
+
+#include "core/fxcrt/fx_safe_types.h"
+
+namespace {
+
+const int32_t kBlockSize = 64 * 1024;
+
+} // namespace
+
+CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive)
+ : m_nTotalSize(0),
+ m_nCurSize(0),
+ m_nCurPos(0),
+ m_nGrowSize(kBlockSize),
+ m_dwFlags(Type::kTakeOver | (bConsecutive ? Type::kConsecutive : 0)) {}
+
+CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer,
+ size_t nSize,
+ bool bTakeOver)
+ : m_nTotalSize(nSize),
+ m_nCurSize(nSize),
+ m_nCurPos(0),
+ m_nGrowSize(kBlockSize),
+ m_dwFlags(Type::kConsecutive | (bTakeOver ? Type::kTakeOver : 0)) {
+ m_Blocks.push_back(pBuffer);
+}
+
+CFX_MemoryStream::~CFX_MemoryStream() {
+ if (m_dwFlags & Type::kTakeOver) {
+ for (uint8_t* pBlock : m_Blocks)
+ FX_Free(pBlock);
+ }
+}
+
+FX_FILESIZE CFX_MemoryStream::GetSize() {
+ return static_cast<FX_FILESIZE>(m_nCurSize);
+}
+
+bool CFX_MemoryStream::IsEOF() {
+ return m_nCurPos >= static_cast<size_t>(GetSize());
+}
+
+FX_FILESIZE CFX_MemoryStream::GetPosition() {
+ return static_cast<FX_FILESIZE>(m_nCurPos);
+}
+
+bool CFX_MemoryStream::Flush() {
+ return true;
+}
+
+bool CFX_MemoryStream::ReadBlock(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ if (!buffer || !size || offset < 0)
+ return false;
+
+ FX_SAFE_SIZE_T newPos = size;
+ newPos += offset;
+ if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 ||
+ newPos.ValueOrDie() > m_nCurSize) {
+ return false;
+ }
+
+ m_nCurPos = newPos.ValueOrDie();
+ if (m_dwFlags & Type::kConsecutive) {
+ memcpy(buffer, m_Blocks[0] + static_cast<size_t>(offset), size);
+ return true;
+ }
+
+ size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize;
+ offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize);
+ while (size) {
+ size_t nRead = std::min(size, m_nGrowSize - static_cast<size_t>(offset));
+ memcpy(buffer, m_Blocks[nStartBlock] + offset, nRead);
+ buffer = static_cast<uint8_t*>(buffer) + nRead;
+ size -= nRead;
+ ++nStartBlock;
+ offset = 0;
+ }
+ return true;
+}
+
+size_t CFX_MemoryStream::ReadBlock(void* buffer, size_t size) {
+ if (m_nCurPos >= m_nCurSize)
+ return 0;
+
+ size_t nRead = std::min(size, m_nCurSize - m_nCurPos);
+ if (!ReadBlock(buffer, static_cast<int32_t>(m_nCurPos), nRead))
+ return 0;
+
+ return nRead;
+}
+
+bool CFX_MemoryStream::WriteBlock(const void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ if (!buffer || !size)
+ return false;
+
+ if (m_dwFlags & Type::kConsecutive) {
+ FX_SAFE_SIZE_T newPos = size;
+ newPos += offset;
+ if (!newPos.IsValid())
+ return false;
+
+ m_nCurPos = newPos.ValueOrDie();
+ if (m_nCurPos > m_nTotalSize) {
+ m_nTotalSize = (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize;
+ if (m_Blocks.empty())
+ m_Blocks.push_back(FX_Alloc(uint8_t, m_nTotalSize));
+ else
+ m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize);
+ }
+
+ memcpy(m_Blocks[0] + offset, buffer, size);
+ m_nCurSize = std::max(m_nCurSize, m_nCurPos);
+
+ return true;
+ }
+
+ FX_SAFE_SIZE_T newPos = size;
+ newPos += offset;
+ if (!newPos.IsValid())
+ return false;
+ if (!ExpandBlocks(newPos.ValueOrDie()))
+ return false;
+
+ m_nCurPos = newPos.ValueOrDie();
+ size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize;
+ offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize);
+ while (size) {
+ size_t nWrite = std::min(size, m_nGrowSize - static_cast<size_t>(offset));
+ memcpy(m_Blocks[nStartBlock] + offset, buffer, nWrite);
+ buffer = static_cast<const uint8_t*>(buffer) + nWrite;
+ size -= nWrite;
+ ++nStartBlock;
+ offset = 0;
+ }
+ return true;
+}
+
+void CFX_MemoryStream::EstimateSize(size_t nInitSize, size_t nGrowSize) {
+ if (m_dwFlags & Type::kConsecutive) {
+ if (m_Blocks.empty()) {
+ m_Blocks.push_back(
+ FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096))));
+ }
+ m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096));
+ } else if (m_Blocks.empty()) {
+ m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096));
+ }
+}
+
+void CFX_MemoryStream::AttachBuffer(uint8_t* pBuffer, size_t nSize) {
+ if (!(m_dwFlags & Type::kConsecutive))
+ return;
+
+ m_Blocks.clear();
+ m_Blocks.push_back(pBuffer);
+ m_nTotalSize = nSize;
+ m_nCurSize = nSize;
+ m_nCurPos = 0;
+ m_dwFlags = Type::kConsecutive;
+}
+
+void CFX_MemoryStream::DetachBuffer() {
+ if (!(m_dwFlags & Type::kConsecutive))
+ return;
+
+ m_Blocks.clear();
+ m_nTotalSize = 0;
+ m_nCurSize = 0;
+ m_nCurPos = 0;
+ m_dwFlags = Type::kTakeOver;
+}
+
+bool CFX_MemoryStream::ExpandBlocks(size_t size) {
+ m_nCurSize = std::max(m_nCurSize, size);
+ if (size <= m_nTotalSize)
+ return true;
+
+ size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize;
+ size_t iCount = m_Blocks.size();
+ m_Blocks.resize(iCount + size);
+ while (size--) {
+ m_Blocks[iCount++] = FX_Alloc(uint8_t, m_nGrowSize);
+ m_nTotalSize += m_nGrowSize;
+ }
+ return true;
+}
diff --git a/core/fxcrt/cfx_memorystream.h b/core/fxcrt/cfx_memorystream.h
new file mode 100644
index 0000000000..2112280237
--- /dev/null
+++ b/core/fxcrt/cfx_memorystream.h
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXCRT_CFX_MEMORYSTREAM_H_
+#define CORE_FXCRT_CFX_MEMORYSTREAM_H_
+
+#include <vector>
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "core/fxcrt/fx_stream.h"
+
+class CFX_MemoryStream : public IFX_SeekableStream {
+ public:
+ enum Type { kConsecutive = 1 << 0, kTakeOver = 1 << 1 };
+
+ template <typename T, typename... Args>
+ friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+ // IFX_SeekableStream
+ FX_FILESIZE GetSize() override;
+ FX_FILESIZE GetPosition() override;
+ bool IsEOF() override;
+ bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+ size_t ReadBlock(void* buffer, size_t size) override;
+ bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
+ bool Flush() override;
+
+ bool IsConsecutive() const { return !!(m_dwFlags & Type::kConsecutive); }
+
+ uint8_t* GetBuffer() const {
+ return !m_Blocks.empty() ? m_Blocks.front() : nullptr;
+ }
+
+ void EstimateSize(size_t nInitSize, size_t nGrowSize);
+ void AttachBuffer(uint8_t* pBuffer, size_t nSize);
+ void DetachBuffer();
+
+ private:
+ explicit CFX_MemoryStream(bool bConsecutive);
+ CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, bool bTakeOver);
+ ~CFX_MemoryStream() override;
+
+ bool ExpandBlocks(size_t size);
+
+ std::vector<uint8_t*> m_Blocks;
+ size_t m_nTotalSize;
+ size_t m_nCurSize;
+ size_t m_nCurPos;
+ size_t m_nGrowSize;
+ uint32_t m_dwFlags;
+};
+
+#endif // CORE_FXCRT_CFX_MEMORYSTREAM_H_
diff --git a/core/fxcrt/cfx_seekablestreamproxy.cpp b/core/fxcrt/cfx_seekablestreamproxy.cpp
index 8be2e0898f..622f56b3ec 100644
--- a/core/fxcrt/cfx_seekablestreamproxy.cpp
+++ b/core/fxcrt/cfx_seekablestreamproxy.cpp
@@ -17,6 +17,7 @@
#include <utility>
#include <vector>
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "third_party/base/ptr_util.h"
@@ -189,7 +190,9 @@ CFX_SeekableStreamProxy::CFX_SeekableStreamProxy(
}
CFX_SeekableStreamProxy::CFX_SeekableStreamProxy(uint8_t* data, FX_STRSIZE size)
- : CFX_SeekableStreamProxy(IFX_MemoryStream::Create(data, size), false) {}
+ : CFX_SeekableStreamProxy(
+ pdfium::MakeRetain<CFX_MemoryStream>(data, size, false),
+ false) {}
CFX_SeekableStreamProxy::~CFX_SeekableStreamProxy() {}
diff --git a/core/fxcrt/fx_stream.cpp b/core/fxcrt/fx_stream.cpp
index a0086f269e..2c451c67b8 100644
--- a/core/fxcrt/fx_stream.cpp
+++ b/core/fxcrt/fx_stream.cpp
@@ -14,10 +14,6 @@
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/ifxcrt_fileaccess.h"
-#define FX_MEMSTREAM_BlockSize (64 * 1024)
-#define FX_MEMSTREAM_Consecutive 0x01
-#define FX_MEMSTREAM_TakeOver 0x02
-
namespace {
class CFX_CRTFileStream final : public IFX_SeekableStream {
@@ -50,222 +46,6 @@ class CFX_CRTFileStream final : public IFX_SeekableStream {
std::unique_ptr<IFXCRT_FileAccess> m_pFile;
};
-class CFX_MemoryStream final : public IFX_MemoryStream {
- public:
- template <typename T, typename... Args>
- friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
- // IFX_MemoryStream
- FX_FILESIZE GetSize() override {
- return static_cast<FX_FILESIZE>(m_nCurSize);
- }
- bool IsEOF() override { return m_nCurPos >= static_cast<size_t>(GetSize()); }
- FX_FILESIZE GetPosition() override {
- return static_cast<FX_FILESIZE>(m_nCurPos);
- }
- bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
- size_t ReadBlock(void* buffer, size_t size) override;
- bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
- bool Flush() override { return true; }
- bool IsConsecutive() const override {
- return !!(m_dwFlags & FX_MEMSTREAM_Consecutive);
- }
- void EstimateSize(size_t nInitSize, size_t nGrowSize) override;
- uint8_t* GetBuffer() const override {
- return !m_Blocks.empty() ? m_Blocks.front() : nullptr;
- }
- void AttachBuffer(uint8_t* pBuffer,
- size_t nSize,
- bool bTakeOver = false) override;
- void DetachBuffer() override;
-
- private:
- explicit CFX_MemoryStream(bool bConsecutive);
- CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, bool bTakeOver);
- ~CFX_MemoryStream() override;
-
- bool ExpandBlocks(size_t size);
-
- std::vector<uint8_t*> m_Blocks;
- size_t m_nTotalSize;
- size_t m_nCurSize;
- size_t m_nCurPos;
- size_t m_nGrowSize;
- uint32_t m_dwFlags;
-};
-
-CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive)
- : m_nTotalSize(0),
- m_nCurSize(0),
- m_nCurPos(0),
- m_nGrowSize(FX_MEMSTREAM_BlockSize) {
- m_dwFlags =
- FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0);
-}
-
-CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer,
- size_t nSize,
- bool bTakeOver)
- : m_nTotalSize(nSize),
- m_nCurSize(nSize),
- m_nCurPos(0),
- m_nGrowSize(FX_MEMSTREAM_BlockSize) {
- m_Blocks.push_back(pBuffer);
- m_dwFlags =
- FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
-}
-
-CFX_MemoryStream::~CFX_MemoryStream() {
- if (m_dwFlags & FX_MEMSTREAM_TakeOver) {
- for (uint8_t* pBlock : m_Blocks)
- FX_Free(pBlock);
- }
-}
-
-bool CFX_MemoryStream::ReadBlock(void* buffer,
- FX_FILESIZE offset,
- size_t size) {
- if (!buffer || !size || offset < 0)
- return false;
-
- FX_SAFE_SIZE_T newPos = size;
- newPos += offset;
- if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 ||
- newPos.ValueOrDie() > m_nCurSize) {
- return false;
- }
-
- m_nCurPos = newPos.ValueOrDie();
- if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
- memcpy(buffer, m_Blocks[0] + static_cast<size_t>(offset), size);
- return true;
- }
-
- size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize;
- offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize);
- while (size) {
- size_t nRead = std::min(size, m_nGrowSize - static_cast<size_t>(offset));
- memcpy(buffer, m_Blocks[nStartBlock] + offset, nRead);
- buffer = static_cast<uint8_t*>(buffer) + nRead;
- size -= nRead;
- ++nStartBlock;
- offset = 0;
- }
- return true;
-}
-
-size_t CFX_MemoryStream::ReadBlock(void* buffer, size_t size) {
- if (m_nCurPos >= m_nCurSize)
- return 0;
-
- size_t nRead = std::min(size, m_nCurSize - m_nCurPos);
- if (!ReadBlock(buffer, static_cast<int32_t>(m_nCurPos), nRead))
- return 0;
-
- return nRead;
-}
-
-bool CFX_MemoryStream::WriteBlock(const void* buffer,
- FX_FILESIZE offset,
- size_t size) {
- if (!buffer || !size)
- return false;
-
- if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
- FX_SAFE_SIZE_T newPos = size;
- newPos += offset;
- if (!newPos.IsValid())
- return false;
-
- m_nCurPos = newPos.ValueOrDie();
- if (m_nCurPos > m_nTotalSize) {
- m_nTotalSize = (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize;
- if (m_Blocks.empty())
- m_Blocks.push_back(FX_Alloc(uint8_t, m_nTotalSize));
- else
- m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize);
- }
-
- memcpy(m_Blocks[0] + offset, buffer, size);
- m_nCurSize = std::max(m_nCurSize, m_nCurPos);
-
- return true;
- }
-
- FX_SAFE_SIZE_T newPos = size;
- newPos += offset;
- if (!newPos.IsValid())
- return false;
- if (!ExpandBlocks(newPos.ValueOrDie()))
- return false;
-
- m_nCurPos = newPos.ValueOrDie();
- size_t nStartBlock = static_cast<size_t>(offset) / m_nGrowSize;
- offset -= static_cast<FX_FILESIZE>(nStartBlock * m_nGrowSize);
- while (size) {
- size_t nWrite = std::min(size, m_nGrowSize - static_cast<size_t>(offset));
- memcpy(m_Blocks[nStartBlock] + offset, buffer, nWrite);
- buffer = static_cast<const uint8_t*>(buffer) + nWrite;
- size -= nWrite;
- ++nStartBlock;
- offset = 0;
- }
- return true;
-}
-
-void CFX_MemoryStream::EstimateSize(size_t nInitSize, size_t nGrowSize) {
- if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
- if (m_Blocks.empty()) {
- m_Blocks.push_back(
- FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096))));
- }
- m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096));
- } else if (m_Blocks.empty()) {
- m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096));
- }
-}
-
-void CFX_MemoryStream::AttachBuffer(uint8_t* pBuffer,
- size_t nSize,
- bool bTakeOver) {
- if (!(m_dwFlags & FX_MEMSTREAM_Consecutive))
- return;
-
- m_Blocks.clear();
- m_Blocks.push_back(pBuffer);
- m_nTotalSize = nSize;
- m_nCurSize = nSize;
- m_nCurPos = 0;
- m_dwFlags =
- FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0);
-}
-
-void CFX_MemoryStream::DetachBuffer() {
- if (!(m_dwFlags & FX_MEMSTREAM_Consecutive))
- return;
-
- m_Blocks.clear();
- m_nTotalSize = 0;
- m_nCurSize = 0;
- m_nCurPos = 0;
- m_dwFlags = FX_MEMSTREAM_TakeOver;
-}
-
-bool CFX_MemoryStream::ExpandBlocks(size_t size) {
- m_nCurSize = std::max(m_nCurSize, size);
- if (size <= m_nTotalSize)
- return true;
-
- size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize;
- size_t iCount = m_Blocks.size();
- m_Blocks.resize(iCount + size);
- while (size--) {
- m_Blocks[iCount++] = FX_Alloc(uint8_t, m_nGrowSize);
- m_nTotalSize += m_nGrowSize;
- }
- return true;
-}
-
} // namespace
// static
@@ -294,18 +74,6 @@ IFX_SeekableReadStream::CreateFromFilename(const char* filename) {
return IFX_SeekableStream::CreateFromFilename(filename, FX_FILEMODE_ReadOnly);
}
-// static
-CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(uint8_t* pBuffer,
- size_t dwSize,
- bool bTakeOver) {
- return pdfium::MakeRetain<CFX_MemoryStream>(pBuffer, dwSize, bTakeOver);
-}
-
-// static
-CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(bool bConsecutive) {
- return pdfium::MakeRetain<CFX_MemoryStream>(bConsecutive);
-}
-
bool IFX_SeekableWriteStream::WriteBlock(const void* pData, size_t size) {
return WriteBlock(pData, GetSize(), size);
}
diff --git a/core/fxcrt/fx_stream.h b/core/fxcrt/fx_stream.h
index 1aa9feae58..5eb83e5681 100644
--- a/core/fxcrt/fx_stream.h
+++ b/core/fxcrt/fx_stream.h
@@ -111,22 +111,6 @@ class IFX_SeekableStream : public IFX_SeekableReadStream,
bool Flush() override = 0;
};
-class IFX_MemoryStream : public IFX_SeekableStream {
- public:
- static CFX_RetainPtr<IFX_MemoryStream> Create(uint8_t* pBuffer,
- size_t nSize,
- bool bTakeOver = false);
- static CFX_RetainPtr<IFX_MemoryStream> Create(bool bConsecutive = false);
-
- virtual bool IsConsecutive() const = 0;
- virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) = 0;
- virtual uint8_t* GetBuffer() const = 0;
- virtual void AttachBuffer(uint8_t* pBuffer,
- size_t nSize,
- bool bTakeOver = false) = 0;
- virtual void DetachBuffer() = 0;
-};
-
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
class CFindFileData {
public:
diff --git a/core/fxcrt/xml/cfx_saxreader_unittest.cpp b/core/fxcrt/xml/cfx_saxreader_unittest.cpp
index 7865d0b77c..0bb5e1a066 100644
--- a/core/fxcrt/xml/cfx_saxreader_unittest.cpp
+++ b/core/fxcrt/xml/cfx_saxreader_unittest.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "core/fxcrt/xml/cfx_saxreader.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/test_support.h"
@@ -50,10 +51,11 @@ class CFX_SAXReaderTest : public pdfium::FPDF_Test {
}
bool StartParse(char* str) {
- return reader_.StartParse(IFX_MemoryStream::Create(
- reinterpret_cast<uint8_t*>(str), strlen(str)),
- 0, static_cast<uint32_t>(-1),
- CFX_SaxParseMode_NotSkipSpace) >= 0;
+ return reader_.StartParse(
+ pdfium::MakeRetain<CFX_MemoryStream>(
+ reinterpret_cast<uint8_t*>(str), strlen(str), false),
+ 0, static_cast<uint32_t>(-1),
+ CFX_SaxParseMode_NotSkipSpace) >= 0;
}
int32_t ContinueParse() {
diff --git a/fpdfsdk/fpdfsave.cpp b/fpdfsdk/fpdfsave.cpp
index a8b0d05c61..8e92579518 100644
--- a/fpdfsdk/fpdfsave.cpp
+++ b/fpdfsdk/fpdfsave.cpp
@@ -16,6 +16,7 @@
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "fpdfsdk/fsdk_define.h"
#include "public/fpdf_edit.h"
@@ -139,8 +140,9 @@ bool SaveXFADocumentData(
CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pTemplateStream);
pAcc->LoadAllData();
- CFX_RetainPtr<IFX_SeekableStream> pTemplate = IFX_MemoryStream::Create(
- const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize());
+ CFX_RetainPtr<IFX_SeekableStream> pTemplate =
+ pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize(), false);
pChecksum->UpdateChecksum(pTemplate);
}
CPDF_Stream* pFormStream = nullptr;
@@ -173,7 +175,8 @@ bool SaveXFADocumentData(
}
// L"datasets"
{
- CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite = IFX_MemoryStream::Create();
+ CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite =
+ pdfium::MakeRetain<CFX_MemoryStream>(false);
if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
nullptr) &&
pDsfileWrite->GetSize() > 0) {
@@ -200,7 +203,8 @@ bool SaveXFADocumentData(
}
// L"form"
{
- CFX_RetainPtr<IFX_SeekableStream> pfileWrite = IFX_MemoryStream::Create();
+ CFX_RetainPtr<IFX_SeekableStream> pfileWrite =
+ pdfium::MakeRetain<CFX_MemoryStream>(false);
if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
pChecksum.get()) &&
pfileWrite->GetSize() > 0) {
diff --git a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
index 7d54cff6da..6769d8e844 100644
--- a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
+++ b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
@@ -4,15 +4,16 @@
#include <memory>
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/cfx_retain_ptr.h"
#include "core/fxcrt/cfx_seekablestreamproxy.h"
#include "core/fxcrt/xml/cfx_saxreader.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
CFX_SAXReader reader;
- if (reader.StartParse(
- IFX_MemoryStream::Create(const_cast<uint8_t*>(data), size), 0, -1,
- CFX_SaxParseMode_NotSkipSpace) < 0) {
+ if (reader.StartParse(pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(data), size, false),
+ 0, -1, CFX_SaxParseMode_NotSkipSpace) < 0) {
return 0;
}
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index 74c284012f..8430d4f834 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -10,8 +10,8 @@
#include <memory>
#include <utility>
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_codepage.h"
-#include "core/fxcrt/fx_stream.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/cfx_gemodule.h"
@@ -982,7 +982,7 @@ CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1);
dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize);
- return IFX_MemoryStream::Create(pBuffer, dwFileSize, true);
+ return pdfium::MakeRetain<CFX_MemoryStream>(pBuffer, dwFileSize, true);
}
CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 5e36c08ff0..228c4948b6 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -15,6 +15,7 @@
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpdf_nametree.h"
#include "core/fxcrt/cfx_checksumcontext.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
@@ -389,8 +390,9 @@ CFX_RetainPtr<CFX_DIBitmap> CXFA_FFDoc::GetPDFNamedImage(
auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
pAcc->LoadAllData();
- CFX_RetainPtr<IFX_SeekableStream> pImageFileRead = IFX_MemoryStream::Create(
- const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize());
+ CFX_RetainPtr<IFX_SeekableStream> pImageFileRead =
+ pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize(), false);
CFX_RetainPtr<CFX_DIBitmap> pDibSource = XFA_LoadImageFromBuffer(
pImageFileRead, FXCODEC_IMAGE_UNKNOWN, iImageXDpi, iImageYDpi);
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 18d6f94bc7..bdadba7c85 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -14,6 +14,7 @@
#include "core/fxcodec/codec/ccodec_progressivedecoder.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/cfx_maybe_owned.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
@@ -1062,12 +1063,14 @@ CFX_RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
pImageBuffer = FX_Alloc(uint8_t, iLength);
int32_t iRead = XFA_Base64Decode(bsData.c_str(), pImageBuffer);
if (iRead > 0) {
- pImageFileRead = IFX_MemoryStream::Create(pImageBuffer, iRead);
+ pImageFileRead =
+ pdfium::MakeRetain<CFX_MemoryStream>(pImageBuffer, iRead, false);
}
} else {
bsContent = CFX_ByteString::FromUnicode(wsImage);
- pImageFileRead = IFX_MemoryStream::Create(
- const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength());
+ pImageFileRead = pdfium::MakeRetain<CFX_MemoryStream>(
+ const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength(),
+ false);
}
} else {
CFX_WideString wsURL = wsHref;
diff --git a/xfa/fxfa/parser/cxfa_dataexporter.cpp b/xfa/fxfa/parser/cxfa_dataexporter.cpp
index 0c702fe53c..70748f2666 100644
--- a/xfa/fxfa/parser/cxfa_dataexporter.cpp
+++ b/xfa/fxfa/parser/cxfa_dataexporter.cpp
@@ -8,6 +8,7 @@
#include <vector>
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/xml/cfx_xmldoc.h"
@@ -224,8 +225,7 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode,
if (!pRichTextXML)
break;
- CFX_RetainPtr<IFX_MemoryStream> pMemStream =
- IFX_MemoryStream::Create(true);
+ auto pMemStream = pdfium::MakeRetain<CFX_MemoryStream>(true);
auto pTempStream =
pdfium::MakeRetain<CFX_SeekableStreamProxy>(pMemStream, true);
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index a3c9ee42e0..d6d2ece428 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -13,6 +13,7 @@
#include <vector>
#include "core/fxcrt/cfx_decimal.h"
+#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
@@ -1406,8 +1407,7 @@ void CXFA_Node::Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments) {
}
XFA_DataExporter_DealWithDataGroupNode(this);
}
- CFX_RetainPtr<IFX_MemoryStream> pMemoryStream =
- IFX_MemoryStream::Create(true);
+ auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>(true);
auto pStream =
pdfium::MakeRetain<CFX_SeekableStreamProxy>(pMemoryStream, true);
pStream->SetCodePage(FX_CODEPAGE_UTF8);