Rename CFX_BinaryBuf to fxcrt::BinaryBuffer and test.

Back-fill some long overdue testing and hit some corner
cases involving zeros.

Change-Id: I5535f43e3835a849fbf8abf8666cac6c06025955
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/95852
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 c055de1..44a2a6a 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -135,7 +135,7 @@
 
 bool CPDF_CryptoHandler::DecryptStream(void* context,
                                        pdfium::span<const uint8_t> source,
-                                       CFX_BinaryBuf& dest_buf) {
+                                       BinaryBuffer& dest_buf) {
   if (!context)
     return false;
 
@@ -183,7 +183,7 @@
   return true;
 }
 
-bool CPDF_CryptoHandler::DecryptFinish(void* context, CFX_BinaryBuf& dest_buf) {
+bool CPDF_CryptoHandler::DecryptFinish(void* context, BinaryBuffer& dest_buf) {
   if (!context)
     return false;
 
@@ -209,7 +209,7 @@
 ByteString CPDF_CryptoHandler::Decrypt(uint32_t objnum,
                                        uint32_t gennum,
                                        const ByteString& str) {
-  CFX_BinaryBuf dest_buf;
+  BinaryBuffer dest_buf;
   void* context = DecryptStart(objnum, gennum);
   DecryptStream(context, str.raw_span(), dest_buf);
   DecryptFinish(context, dest_buf);
@@ -275,7 +275,7 @@
           continue;
         }
 
-        CFX_BinaryBuf decrypted_buf;
+        BinaryBuffer decrypted_buf;
         decrypted_buf.EstimateSize(DecryptGetSize(stream_access->GetSize()));
 
         void* context = DecryptStart(obj_num, gen_num);
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.h b/core/fpdfapi/parser/cpdf_crypto_handler.h
index 354126b..896ad83 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.h
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.h
@@ -13,8 +13,8 @@
 #include <memory>
 
 #include "core/fdrm/fx_crypt.h"
+#include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/bytestring.h"
-#include "core/fxcrt/cfx_binarybuf.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "third_party/base/span.h"
@@ -52,8 +52,8 @@
   ByteString Decrypt(uint32_t objnum, uint32_t gennum, const ByteString& str);
   bool DecryptStream(void* context,
                      pdfium::span<const uint8_t> source,
-                     CFX_BinaryBuf& dest_buf);
-  bool DecryptFinish(void* context, CFX_BinaryBuf& dest_buf);
+                     BinaryBuffer& dest_buf);
+  bool DecryptFinish(void* context, BinaryBuffer& dest_buf);
   void PopulateKey(uint32_t objnum, uint32_t gennum, uint8_t* key) const;
 
   const size_t m_KeyLen;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 9e1b350..55669c9 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -24,7 +24,6 @@
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
 #include "core/fxcrt/autorestorer.h"
-#include "core/fxcrt/cfx_binarybuf.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "third_party/base/check.h"
diff --git a/core/fxcodec/fax/faxmodule.cpp b/core/fxcodec/fax/faxmodule.cpp
index 753cd6e..def5fdf 100644
--- a/core/fxcodec/fax/faxmodule.cpp
+++ b/core/fxcodec/fax/faxmodule.cpp
@@ -13,7 +13,7 @@
 
 #include "build/build_config.h"
 #include "core/fxcodec/scanlinedecoder.h"
-#include "core/fxcrt/cfx_binarybuf.h"
+#include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/stl_util.h"
 #include "core/fxge/calculate_pitch.h"
@@ -688,7 +688,7 @@
   const int m_Rows;
   const int m_Pitch;
   const uint8_t* m_pSrcBuf;
-  CFX_BinaryBuf m_DestBuf;
+  BinaryBuffer m_DestBuf;
   std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_RefLine;
   std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_LineBuf;
 };
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 865516a..fc83402 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -14,11 +14,11 @@
   sources = [
     "autonuller.h",
     "autorestorer.h",
+    "binary_buffer.cpp",
+    "binary_buffer.h",
     "byteorder.h",
     "bytestring.cpp",
     "bytestring.h",
-    "cfx_binarybuf.cpp",
-    "cfx_binarybuf.h",
     "cfx_bitstream.cpp",
     "cfx_bitstream.h",
     "cfx_datetime.cpp",
@@ -152,6 +152,7 @@
   sources = [
     "autonuller_unittest.cpp",
     "autorestorer_unittest.cpp",
+    "binary_buffer_unittest.cpp",
     "byteorder_unittest.cpp",
     "bytestring_unittest.cpp",
     "cfx_bitstream_unittest.cpp",
diff --git a/core/fxcrt/cfx_binarybuf.cpp b/core/fxcrt/binary_buffer.cpp
similarity index 69%
rename from core/fxcrt/cfx_binarybuf.cpp
rename to core/fxcrt/binary_buffer.cpp
index 512c64c..4f862c5 100644
--- a/core/fxcrt/cfx_binarybuf.cpp
+++ b/core/fxcrt/binary_buffer.cpp
@@ -4,16 +4,18 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "core/fxcrt/cfx_binarybuf.h"
+#include "core/fxcrt/binary_buffer.h"
 
 #include <algorithm>
 #include <utility>
 
 #include "core/fxcrt/fx_safe_types.h"
 
-CFX_BinaryBuf::CFX_BinaryBuf() = default;
+namespace fxcrt {
 
-CFX_BinaryBuf::CFX_BinaryBuf(CFX_BinaryBuf&& that) noexcept
+BinaryBuffer::BinaryBuffer() = default;
+
+BinaryBuffer::BinaryBuffer(BinaryBuffer&& that) noexcept
     : m_AllocStep(that.m_AllocStep),
       m_AllocSize(that.m_AllocSize),
       m_DataSize(that.m_DataSize),
@@ -25,9 +27,9 @@
   that.m_DataSize = 0;
 }
 
-CFX_BinaryBuf::~CFX_BinaryBuf() = default;
+BinaryBuffer::~BinaryBuffer() = default;
 
-CFX_BinaryBuf& CFX_BinaryBuf::operator=(CFX_BinaryBuf&& that) noexcept {
+BinaryBuffer& BinaryBuffer::operator=(BinaryBuffer&& that) noexcept {
   // Can't just default, need to leave |that| in a valid state, which means
   // that the size members reflect the (null) moved-from buffer.
   m_AllocStep = that.m_AllocStep;
@@ -40,7 +42,7 @@
   return *this;
 }
 
-void CFX_BinaryBuf::DeleteBuf(size_t start_index, size_t count) {
+void BinaryBuffer::DeleteBuf(size_t start_index, size_t count) {
   if (!m_pBuffer || count > m_DataSize || start_index > m_DataSize - count)
     return;
 
@@ -49,34 +51,34 @@
   m_DataSize -= count;
 }
 
-pdfium::span<uint8_t> CFX_BinaryBuf::GetSpan() {
+pdfium::span<uint8_t> BinaryBuffer::GetSpan() {
   return {m_pBuffer.get(), GetSize()};
 }
 
-pdfium::span<const uint8_t> CFX_BinaryBuf::GetSpan() const {
+pdfium::span<const uint8_t> BinaryBuffer::GetSpan() const {
   return {m_pBuffer.get(), GetSize()};
 }
 
-size_t CFX_BinaryBuf::GetLength() const {
+size_t BinaryBuffer::GetLength() const {
   return m_DataSize;
 }
 
-void CFX_BinaryBuf::Clear() {
+void BinaryBuffer::Clear() {
   m_DataSize = 0;
 }
 
-std::unique_ptr<uint8_t, FxFreeDeleter> CFX_BinaryBuf::DetachBuffer() {
+std::unique_ptr<uint8_t, FxFreeDeleter> BinaryBuffer::DetachBuffer() {
   m_DataSize = 0;
   m_AllocSize = 0;
   return std::move(m_pBuffer);
 }
 
-void CFX_BinaryBuf::EstimateSize(size_t size) {
+void BinaryBuffer::EstimateSize(size_t size) {
   if (m_AllocSize < size)
     ExpandBuf(size - m_DataSize);
 }
 
-void CFX_BinaryBuf::ExpandBuf(size_t add_size) {
+void BinaryBuffer::ExpandBuf(size_t add_size) {
   FX_SAFE_SIZE_T new_size = m_DataSize;
   new_size += add_size;
   if (m_AllocSize >= new_size.ValueOrDie())
@@ -93,11 +95,11 @@
                       : FX_Alloc(uint8_t, m_AllocSize));
 }
 
-void CFX_BinaryBuf::AppendSpan(pdfium::span<const uint8_t> span) {
+void BinaryBuffer::AppendSpan(pdfium::span<const uint8_t> span) {
   return AppendBlock(span.data(), span.size());
 }
 
-void CFX_BinaryBuf::AppendBlock(const void* pBuf, size_t size) {
+void BinaryBuffer::AppendBlock(const void* pBuf, size_t size) {
   if (size == 0)
     return;
 
@@ -109,3 +111,14 @@
   }
   m_DataSize += size;
 }
+
+void BinaryBuffer::AppendString(const ByteString& str) {
+  AppendBlock(str.c_str(), str.GetLength());
+}
+
+void BinaryBuffer::AppendByte(uint8_t byte) {
+  ExpandBuf(1);
+  m_pBuffer.get()[m_DataSize++] = byte;
+}
+
+}  // namespace fxcrt
diff --git a/core/fxcrt/cfx_binarybuf.h b/core/fxcrt/binary_buffer.h
similarity index 70%
rename from core/fxcrt/cfx_binarybuf.h
rename to core/fxcrt/binary_buffer.h
index d633d8a..bca0f75 100644
--- a/core/fxcrt/cfx_binarybuf.h
+++ b/core/fxcrt/binary_buffer.h
@@ -4,8 +4,8 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef CORE_FXCRT_CFX_BINARYBUF_H_
-#define CORE_FXCRT_CFX_BINARYBUF_H_
+#ifndef CORE_FXCRT_BINARY_BUFFER_H_
+#define CORE_FXCRT_BINARY_BUFFER_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -16,14 +16,19 @@
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "third_party/base/span.h"
 
-class CFX_BinaryBuf {
+namespace fxcrt {
+
+class BinaryBuffer {
  public:
-  CFX_BinaryBuf();
-  CFX_BinaryBuf(CFX_BinaryBuf&& that) noexcept;
-  virtual ~CFX_BinaryBuf();
+  BinaryBuffer();
+  BinaryBuffer(BinaryBuffer&& that) noexcept;
+  BinaryBuffer(const BinaryBuffer& that) = delete;
+  virtual ~BinaryBuffer();
 
   // Moved-from value will be left empty.
-  CFX_BinaryBuf& operator=(CFX_BinaryBuf&& that) noexcept;
+  BinaryBuffer& operator=(BinaryBuffer&& that) noexcept;
+
+  BinaryBuffer& operator=(const BinaryBuffer& that) = delete;
 
   pdfium::span<uint8_t> GetSpan();
   pdfium::span<const uint8_t> GetSpan() const;
@@ -36,14 +41,8 @@
   void EstimateSize(size_t size);
   void AppendSpan(pdfium::span<const uint8_t> span);
   void AppendBlock(const void* pBuf, size_t size);
-  void AppendString(const ByteString& str) {
-    AppendBlock(str.c_str(), str.GetLength());
-  }
-
-  void AppendByte(uint8_t byte) {
-    ExpandBuf(1);
-    m_pBuffer.get()[m_DataSize++] = byte;
-  }
+  void AppendString(const ByteString& str);
+  void AppendByte(uint8_t byte);
 
   // Releases ownership of |m_pBuffer| and returns it.
   std::unique_ptr<uint8_t, FxFreeDeleter> DetachBuffer();
@@ -58,4 +57,8 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> m_pBuffer;
 };
 
-#endif  // CORE_FXCRT_CFX_BINARYBUF_H_
+}  // namespace fxcrt
+
+using fxcrt::BinaryBuffer;
+
+#endif  // CORE_FXCRT_BINARY_BUFFER_H_
diff --git a/core/fxcrt/binary_buffer_unittest.cpp b/core/fxcrt/binary_buffer_unittest.cpp
new file mode 100644
index 0000000..7c1e927
--- /dev/null
+++ b/core/fxcrt/binary_buffer_unittest.cpp
@@ -0,0 +1,122 @@
+// 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/binary_buffer.h"
+
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/bytestring.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace fxcrt {
+
+TEST(BinaryBuffer, Empty) {
+  BinaryBuffer buffer;
+  EXPECT_TRUE(buffer.IsEmpty());
+  EXPECT_EQ(0u, buffer.GetSize());
+  EXPECT_EQ(0u, buffer.GetLength());
+  EXPECT_TRUE(buffer.GetSpan().empty());
+}
+
+TEST(BinaryBuffer, MoveConstruct) {
+  BinaryBuffer buffer;
+  buffer.AppendByte(65u);
+
+  BinaryBuffer buffer2(std::move(buffer));
+
+  EXPECT_TRUE(buffer.IsEmpty());
+  EXPECT_EQ(0u, buffer.GetSize());
+  EXPECT_EQ(0u, buffer.GetLength());
+  EXPECT_TRUE(buffer.GetSpan().empty());
+
+  EXPECT_FALSE(buffer2.IsEmpty());
+  EXPECT_EQ(1u, buffer2.GetSize());
+  EXPECT_EQ(1u, buffer2.GetLength());
+  EXPECT_EQ(65u, buffer2.GetSpan()[0]);
+}
+
+TEST(BinaryBuffer, MoveAssign) {
+  BinaryBuffer buffer;
+  BinaryBuffer buffer2;
+  buffer.AppendByte(65u);
+  buffer2 = std::move(buffer);
+
+  EXPECT_TRUE(buffer.IsEmpty());
+  EXPECT_EQ(0u, buffer.GetSize());
+  EXPECT_EQ(0u, buffer.GetLength());
+  EXPECT_TRUE(buffer.GetSpan().empty());
+
+  EXPECT_FALSE(buffer2.IsEmpty());
+  EXPECT_EQ(1u, buffer2.GetSize());
+  ASSERT_EQ(1u, buffer2.GetLength());
+  EXPECT_EQ(65u, buffer2.GetSpan()[0]);
+}
+
+TEST(BinaryBuffer, Clear) {
+  BinaryBuffer buffer;
+  buffer.AppendByte(65u);
+  buffer.Clear();
+  EXPECT_TRUE(buffer.IsEmpty());
+  EXPECT_EQ(0u, buffer.GetSize());
+  EXPECT_EQ(0u, buffer.GetLength());
+  EXPECT_TRUE(buffer.GetSpan().empty());
+}
+
+TEST(BinaryBuffer, AppendSpans) {
+  BinaryBuffer buffer;
+  std::vector<uint8_t> aaa(3, 65u);
+  std::vector<uint8_t> bbb(3, 66u);
+  buffer.AppendSpan(aaa);
+  buffer.AppendSpan(bbb);
+  EXPECT_FALSE(buffer.IsEmpty());
+  EXPECT_EQ(6u, buffer.GetSize());
+  EXPECT_EQ(6u, buffer.GetLength());
+  EXPECT_EQ(65u, buffer.GetSpan()[0]);
+  EXPECT_EQ(65u, buffer.GetSpan()[1]);
+  EXPECT_EQ(65u, buffer.GetSpan()[2]);
+  EXPECT_EQ(66u, buffer.GetSpan()[3]);
+  EXPECT_EQ(66u, buffer.GetSpan()[4]);
+  EXPECT_EQ(66u, buffer.GetSpan()[5]);
+}
+
+TEST(BinaryBuffer, AppendBlocks) {
+  BinaryBuffer buffer;
+  std::vector<uint8_t> aaa(3, 65u);
+  std::vector<uint8_t> bbb(3, 66u);
+  buffer.AppendBlock(aaa.data(), aaa.size());
+  buffer.AppendBlock(bbb.data(), bbb.size());
+  EXPECT_EQ(6u, buffer.GetSize());
+  EXPECT_EQ(6u, buffer.GetLength());
+  EXPECT_EQ(65u, buffer.GetSpan()[0]);
+  EXPECT_EQ(65u, buffer.GetSpan()[1]);
+  EXPECT_EQ(65u, buffer.GetSpan()[2]);
+  EXPECT_EQ(66u, buffer.GetSpan()[3]);
+  EXPECT_EQ(66u, buffer.GetSpan()[4]);
+  EXPECT_EQ(66u, buffer.GetSpan()[5]);
+}
+
+TEST(BinaryBuffer, AppendStrings) {
+  BinaryBuffer buffer;
+  buffer.AppendString("AA");
+  buffer.AppendString("BB");
+  EXPECT_EQ(4u, buffer.GetSize());
+  EXPECT_EQ(4u, buffer.GetLength());
+  EXPECT_EQ(65u, buffer.GetSpan()[0]);
+  EXPECT_EQ(65u, buffer.GetSpan()[1]);
+  EXPECT_EQ(66u, buffer.GetSpan()[2]);
+  EXPECT_EQ(66u, buffer.GetSpan()[3]);
+}
+
+TEST(BinaryBuffer, AppendBytes) {
+  BinaryBuffer buffer;
+  buffer.AppendByte(65u);
+  buffer.AppendByte(66u);
+  EXPECT_EQ(2u, buffer.GetSize());
+  EXPECT_EQ(2u, buffer.GetLength());
+  EXPECT_EQ(65u, buffer.GetSpan()[0]);
+  EXPECT_EQ(66u, buffer.GetSpan()[1]);
+}
+
+}  // namespace fxcrt
diff --git a/core/fxcrt/cfx_widetextbuf.h b/core/fxcrt/cfx_widetextbuf.h
index 223e8c6..33fc53a 100644
--- a/core/fxcrt/cfx_widetextbuf.h
+++ b/core/fxcrt/cfx_widetextbuf.h
@@ -9,13 +9,13 @@
 
 #include <stddef.h>
 
-#include "core/fxcrt/cfx_binarybuf.h"
+#include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/fx_string.h"
 #include "third_party/base/span.h"
 
-class CFX_WideTextBuf final : public CFX_BinaryBuf {
+class CFX_WideTextBuf final : public BinaryBuffer {
  public:
-  // CFX_BinaryBuf:
+  // BinaryBuffer:
   size_t GetLength() const override;
 
   pdfium::span<wchar_t> GetWideSpan();
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index a765c9a..1898703 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -40,7 +40,7 @@
 
 void MakeNameTypeString(const ByteString& name,
                         CFX_Value::DataType eType,
-                        CFX_BinaryBuf* result) {
+                        BinaryBuffer* result) {
   uint32_t dwNameLen = (uint32_t)name.GetLength();
   result->AppendBlock(&dwNameLen, sizeof(uint32_t));
   result->AppendString(name);
@@ -51,7 +51,7 @@
 
 bool MakeByteString(const ByteString& name,
                     const CFX_KeyValue& pData,
-                    CFX_BinaryBuf* result) {
+                    BinaryBuffer* result) {
   switch (pData.nType) {
     case CFX_Value::DataType::kNumber: {
       MakeNameTypeString(name, pData.nType, result);
@@ -362,12 +362,12 @@
     return false;
 
   uint32_t nCount = 0;
-  CFX_BinaryBuf sData;
+  BinaryBuffer sData;
   for (const auto& pElement : m_arrayGlobalData) {
     if (!pElement->bPersistent)
       continue;
 
-    CFX_BinaryBuf sElement;
+    BinaryBuffer sElement;
     if (!MakeByteString(pElement->data.sKey, pElement->data, &sElement))
       continue;
 
@@ -378,7 +378,7 @@
     nCount++;
   }
 
-  CFX_BinaryBuf sFile;
+  BinaryBuffer sFile;
   uint16_t wType = kMagic;
   uint16_t wVersion = 2;
   sFile.AppendBlock(&wType, sizeof(uint16_t));
diff --git a/fxjs/cfx_globaldata.h b/fxjs/cfx_globaldata.h
index 86ce5c7..7ba24b9 100644
--- a/fxjs/cfx_globaldata.h
+++ b/fxjs/cfx_globaldata.h
@@ -10,7 +10,7 @@
 #include <memory>
 #include <vector>
 
-#include "core/fxcrt/cfx_binarybuf.h"
+#include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/cfx_keyvalue.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"