Support V8_ENABLE_SANDBOX in CFX_ArrayBufferAllocator

Allow tests to run under a full chromium checkout, without forcing a
fallback from PA to malloc() for standalone checkouts.

Bug: chromium:1325244
Change-Id: Ib7596aeb02ca32746bb840573c874de78129c5a9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/103216
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cfx_v8_array_buffer_allocator.cpp b/fxjs/cfx_v8_array_buffer_allocator.cpp
index 948ecd4..c0ddad0 100644
--- a/fxjs/cfx_v8_array_buffer_allocator.cpp
+++ b/fxjs/cfx_v8_array_buffer_allocator.cpp
@@ -8,18 +8,46 @@
 
 #include "core/fxcrt/fx_memory.h"
 
+CFX_V8ArrayBufferAllocator::CFX_V8ArrayBufferAllocator() = default;
+
+CFX_V8ArrayBufferAllocator::~CFX_V8ArrayBufferAllocator() = default;
+
+// NOTE: Under V8 sandbox mode, defer NewDefaultAllocator() call until
+// first use, since V8 must be initialized first for it to succeed, but
+// we need the allocator in order to initialize V8.
+
 void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
   if (length > kMaxAllowedBytes)
     return nullptr;
+#ifdef V8_ENABLE_SANDBOX
+  if (!wrapped_) {
+    wrapped_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+  }
+  return wrapped_->Allocate(length);
+#else   // V8_ENABLE_SANDBOX
   return FX_ArrayBufferAllocate(length);
+#endif  // V8_ENABLE_SANDBOX
 }
 
 void* CFX_V8ArrayBufferAllocator::AllocateUninitialized(size_t length) {
   if (length > kMaxAllowedBytes)
     return nullptr;
+#ifdef V8_ENABLE_SANDBOX
+  if (!wrapped_) {
+    wrapped_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+  }
+  return wrapped_->AllocateUninitialized(length);
+#else  // V8_ENABLE_SANDBOX
   return FX_ArrayBufferAllocateUninitialized(length);
+#endif
 }
 
 void CFX_V8ArrayBufferAllocator::Free(void* data, size_t length) {
+#ifdef V8_ENABLE_SANDBOX
+  if (wrapped_) {
+    wrapped_->Free(data, length);
+  }
+#else  // V8_ENABLE_SANDBOX
   FX_ArrayBufferFree(data);
+#endif
 }
diff --git a/fxjs/cfx_v8_array_buffer_allocator.h b/fxjs/cfx_v8_array_buffer_allocator.h
index d3c5cdb..a6daef0 100644
--- a/fxjs/cfx_v8_array_buffer_allocator.h
+++ b/fxjs/cfx_v8_array_buffer_allocator.h
@@ -9,13 +9,27 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "v8/include/v8-array-buffer.h"
 
 class CFX_V8ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
+ public:
   static const size_t kMaxAllowedBytes = 0x10000000;
+
+  CFX_V8ArrayBufferAllocator();
+  CFX_V8ArrayBufferAllocator(const CFX_V8ArrayBufferAllocator&) = delete;
+  CFX_V8ArrayBufferAllocator(CFX_V8ArrayBufferAllocator&&) = delete;
+  ~CFX_V8ArrayBufferAllocator() override;
+
   void* Allocate(size_t length) override;
   void* AllocateUninitialized(size_t length) override;
   void Free(void* data, size_t length) override;
+
+#ifdef V8_ENABLE_SANDBOX
+ private:
+  std::unique_ptr<v8::ArrayBuffer::Allocator> wrapped_;
+#endif  // V8_ENABLE_SANDBOX
 };
 
 #endif  // FXJS_CFX_V8_ARRAY_BUFFER_ALLOCATOR_H_