Introduce FX_STACK_ALLOCATED() macro.

Consolidate the code that enforces stack allocation, as other
projects have done.

In particular, this fixes cases in cfxjse_isolatetracker.cpp that
were not quite sufficient to stop some non-stack allocations.

-- Move FX_Free() closer to related functions as long as we're
   touching fx_memory.h.

Change-Id: Ie85ed32ffdd35bd67e4a0c453e0ecb4e7cb13ad5
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/80371
Auto-Submit: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_read_validator.h b/core/fpdfapi/parser/cpdf_read_validator.h
index ba07dfa..439d904 100644
--- a/core/fpdfapi/parser/cpdf_read_validator.h
+++ b/core/fpdfapi/parser/cpdf_read_validator.h
@@ -6,6 +6,7 @@
 #define CORE_FPDFAPI_PARSER_CPDF_READ_VALIDATOR_H_
 
 #include "core/fpdfapi/parser/cpdf_data_avail.h"
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_stream.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
@@ -14,16 +15,14 @@
  public:
   class ScopedSession {
    public:
+    FX_STACK_ALLOCATED();
+
     explicit ScopedSession(RetainPtr<CPDF_ReadValidator> validator);
     ScopedSession(const ScopedSession& that) = delete;
     ScopedSession& operator=(const ScopedSession& that) = delete;
     ~ScopedSession();
 
    private:
-    // Make stack-allocated.
-    void* operator new(size_t) = delete;
-    void* operator new(size_t, void*) = delete;
-
     RetainPtr<CPDF_ReadValidator> const validator_;
     const bool saved_read_error_;
     const bool saved_has_unavailable_data_;
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 778c5df..979a70d 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -51,6 +51,7 @@
 #include "core/fpdfapi/render/cpdf_textrenderer.h"
 #include "core/fpdfapi/render/cpdf_type3cache.h"
 #include "core/fxcrt/autorestorer.h"
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/unowned_ptr.h"
@@ -146,6 +147,8 @@
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
 class ScopedSkiaDeviceFlush {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit ScopedSkiaDeviceFlush(CFX_RenderDevice* pDevice)
       : m_pDevice(pDevice) {}
 
diff --git a/core/fpdfdoc/cpdf_formfield_unittest.cpp b/core/fpdfdoc/cpdf_formfield_unittest.cpp
index 9db7510..9766924 100644
--- a/core/fpdfdoc/cpdf_formfield_unittest.cpp
+++ b/core/fpdfdoc/cpdf_formfield_unittest.cpp
@@ -20,6 +20,7 @@
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/render/cpdf_docrenderdata.h"
 #include "core/fpdfdoc/cpdf_interactiveform.h"
+#include "core/fxcrt/fx_memory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/base/stl_util.h"
 
@@ -29,6 +30,8 @@
 // CPDF_Document.
 class ScopedCPDF_PageModule {
  public:
+  FX_STACK_ALLOCATED();
+
   ScopedCPDF_PageModule() { CPDF_PageModule::Create(); }
   ~ScopedCPDF_PageModule() { CPDF_PageModule::Destroy(); }
 };
diff --git a/core/fxcrt/fx_memory.h b/core/fxcrt/fx_memory.h
index 3312191..f6d04f4 100644
--- a/core/fxcrt/fx_memory.h
+++ b/core/fxcrt/fx_memory.h
@@ -58,6 +58,8 @@
 #define FX_AllocUninit2D(type, w, h) \
   static_cast<type*>(pdfium::internal::AllocOrDie2D(w, h, sizeof(type)))
 
+void FX_Free(void* ptr);
+
 namespace pdfium {
 namespace internal {
 
@@ -74,7 +76,10 @@
 }  // namespace internal
 }  // namespace pdfium
 
-void FX_Free(void* ptr);
+// Force stack allocation of a class.
+#define FX_STACK_ALLOCATED()           \
+  void* operator new(size_t) = delete; \
+  void* operator new(size_t, void*) = delete
 
 // Round up to the power-of-two boundary N.
 template <int N, typename T>
diff --git a/core/fxcrt/scoped_set_insertion.h b/core/fxcrt/scoped_set_insertion.h
index 890e75f..35b3b0a 100644
--- a/core/fxcrt/scoped_set_insertion.h
+++ b/core/fxcrt/scoped_set_insertion.h
@@ -8,6 +8,7 @@
 #include <set>
 #include <utility>
 
+#include "core/fxcrt/fx_memory.h"
 #include "third_party/base/check.h"
 
 namespace fxcrt {
@@ -17,6 +18,8 @@
 template <typename T>
 class ScopedSetInsertion {
  public:
+  FX_STACK_ALLOCATED();
+
   ScopedSetInsertion(std::set<T>* org_set, const T& elem)
       : set_(org_set), insert_results_(set_->insert(elem)) {
     CHECK(insert_results_.second);
@@ -25,10 +28,6 @@
   ScopedSetInsertion& operator=(const ScopedSetInsertion&) = delete;
   ~ScopedSetInsertion() { set_->erase(insert_results_.first); }
 
-  // Stack allocated only.
-  void* operator new(size_t) = delete;
-  void* operator new(size_t, void*) = delete;
-
  private:
   std::set<T>* const set_;
   const std::pair<typename std::set<T>::iterator, bool> insert_results_;
diff --git a/core/fxge/scoped_font_transform.h b/core/fxge/scoped_font_transform.h
index d96d4ed..f4e7b1e 100644
--- a/core/fxge/scoped_font_transform.h
+++ b/core/fxge/scoped_font_transform.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXGE_SCOPED_FONT_TRANSFORM_H_
 #define CORE_FXGE_SCOPED_FONT_TRANSFORM_H_
 
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_face.h"
 #include "core/fxge/fx_freetype.h"
@@ -15,6 +16,8 @@
 // goes out of scope.
 class ScopedFontTransform {
  public:
+  FX_STACK_ALLOCATED();
+
   ScopedFontTransform(RetainPtr<CFX_Face> face, FT_Matrix* matrix);
   ~ScopedFontTransform();
 
diff --git a/core/fxge/win32/cgdi_printer_driver.cpp b/core/fxge/win32/cgdi_printer_driver.cpp
index d7f4981..51b1646 100644
--- a/core/fxge/win32/cgdi_printer_driver.cpp
+++ b/core/fxge/win32/cgdi_printer_driver.cpp
@@ -12,6 +12,7 @@
 #include <memory>
 #include <vector>
 
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_font.h"
@@ -28,6 +29,8 @@
 
 class ScopedState {
  public:
+  FX_STACK_ALLOCATED();
+
   ScopedState(HDC hDC, HFONT hFont)
       : m_hDC(hDC),
         m_iState(SaveDC(m_hDC)),
diff --git a/fxjs/ijs_runtime.h b/fxjs/ijs_runtime.h
index e18b8d4..97e30aa 100644
--- a/fxjs/ijs_runtime.h
+++ b/fxjs/ijs_runtime.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/unowned_ptr.h"
@@ -33,6 +34,8 @@
 
   class ScopedEventContext {
    public:
+    FX_STACK_ALLOCATED();
+
     explicit ScopedEventContext(IJS_Runtime* pRuntime);
     ~ScopedEventContext();
 
diff --git a/fxjs/xfa/cfxjse_isolatetracker.h b/fxjs/xfa/cfxjse_isolatetracker.h
index 3e78c57..3b0b058 100644
--- a/fxjs/xfa/cfxjse_isolatetracker.h
+++ b/fxjs/xfa/cfxjse_isolatetracker.h
@@ -7,12 +7,15 @@
 #ifndef FXJS_XFA_CFXJSE_ISOLATETRACKER_H_
 #define FXJS_XFA_CFXJSE_ISOLATETRACKER_H_
 
+#include "core/fxcrt/fx_memory.h"
 #include "v8/include/v8.h"
 
 class CFXJSE_Context;
 
 class CFXJSE_ScopeUtil_IsolateHandle {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate);
   CFXJSE_ScopeUtil_IsolateHandle(const CFXJSE_ScopeUtil_IsolateHandle&) =
       delete;
@@ -21,29 +24,27 @@
   ~CFXJSE_ScopeUtil_IsolateHandle();
 
  private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
   v8::Isolate::Scope isolate_scope_;
   v8::HandleScope handle_scope_;
 };
 
 class CFXJSE_ScopeUtil_Context {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit CFXJSE_ScopeUtil_Context(CFXJSE_Context* pContext);
   CFXJSE_ScopeUtil_Context(const CFXJSE_ScopeUtil_Context&) = delete;
   CFXJSE_ScopeUtil_Context& operator=(const CFXJSE_ScopeUtil_Context&) = delete;
   ~CFXJSE_ScopeUtil_Context();
 
  private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
   v8::Context::Scope context_scope_;
 };
 
 class CFXJSE_ScopeUtil_IsolateHandleContext {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext);
   CFXJSE_ScopeUtil_IsolateHandleContext(
       const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
@@ -52,15 +53,14 @@
   ~CFXJSE_ScopeUtil_IsolateHandleContext();
 
  private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
   CFXJSE_ScopeUtil_IsolateHandle isolate_handle_;
   CFXJSE_ScopeUtil_Context context_;
 };
 
 class CFXJSE_ScopeUtil_RootContext {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit CFXJSE_ScopeUtil_RootContext(v8::Isolate* pIsolate);
   CFXJSE_ScopeUtil_RootContext(const CFXJSE_ScopeUtil_RootContext&) = delete;
   CFXJSE_ScopeUtil_RootContext& operator=(const CFXJSE_ScopeUtil_RootContext&) =
@@ -68,14 +68,13 @@
   ~CFXJSE_ScopeUtil_RootContext();
 
  private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
   v8::Context::Scope context_scope_;
 };
 
 class CFXJSE_ScopeUtil_IsolateHandleRootContext {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate);
   CFXJSE_ScopeUtil_IsolateHandleRootContext(
       const CFXJSE_ScopeUtil_IsolateHandleRootContext&) = delete;
@@ -84,9 +83,6 @@
   ~CFXJSE_ScopeUtil_IsolateHandleRootContext();
 
  private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
   CFXJSE_ScopeUtil_IsolateHandle isolate_handle_;
   CFXJSE_ScopeUtil_RootContext root_context_;
 };
diff --git a/testing/scoped_set_tz.h b/testing/scoped_set_tz.h
index 37a0a32..19c633c 100644
--- a/testing/scoped_set_tz.h
+++ b/testing/scoped_set_tz.h
@@ -7,10 +7,13 @@
 
 #include <string>
 
+#include "core/fxcrt/fx_memory.h"
 #include "third_party/base/optional.h"
 
 class ScopedSetTZ {
  public:
+  FX_STACK_ALLOCATED();
+
   explicit ScopedSetTZ(const std::string& tz);
   ScopedSetTZ(const ScopedSetTZ&) = delete;
   ScopedSetTZ& operator=(const ScopedSetTZ&) = delete;