This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 84527aaae39662a21024d07aaed672fbfef6bb68
Author: Chris McFarlen <ch...@mcfarlen.us>
AuthorDate: Fri Sep 5 10:32:30 2025 -0500

    Fallback to malloc for larger regex buffers (#12465)
    
    * Fallback to malloc for larger regex buffers
    
    * assert on match fail, better description in free.
    
    (cherry picked from commit 9286caac06c21eab0fe8f674d061f33caed6847c)
---
 include/tsutil/Regex.h |  1 +
 src/tsutil/Regex.cc    | 28 +++++++++++++++++++---------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/include/tsutil/Regex.h b/include/tsutil/Regex.h
index 9852269e1c..7daaf5c453 100644
--- a/include/tsutil/Regex.h
+++ b/include/tsutil/Regex.h
@@ -66,6 +66,7 @@ public:
 private:
   constexpr static uint32_t DEFAULT_MATCHES = 10;
   static void              *malloc(size_t size, void *caller);
+  static void               free(void *p, void *caller);
   std::string_view          _subject;
   char    _buffer[24 + 96 + 28 * DEFAULT_MATCHES]; // 24 bytes for the general 
context, 96 bytes overhead, 28 bytes per match.
   size_t  _buffer_bytes_used = 0;
diff --git a/src/tsutil/Regex.cc b/src/tsutil/Regex.cc
index d1410da32e..26a1dcc87c 100644
--- a/src/tsutil/Regex.cc
+++ b/src/tsutil/Regex.cc
@@ -126,15 +126,10 @@ struct RegexMatches::_MatchData {
 //----------------------------------------------------------------------------
 RegexMatches::RegexMatches(uint32_t size)
 {
-  pcre2_general_context *ctx =
-    pcre2_general_context_create(&RegexMatches::malloc, [](void *, void *) -> 
void {}, static_cast<void *>(this));
+  pcre2_general_context *ctx = 
pcre2_general_context_create(&RegexMatches::malloc, &RegexMatches::free, 
static_cast<void *>(this));
 
   pcre2_match_data *match_data = pcre2_match_data_create(size, ctx);
-  if (match_data == nullptr) {
-    // buffer was too small, allocate from heap
-    debug_assert_message(false, "RegexMatches data buffer too small, increase 
the buffer size in Regex.h");
-    match_data = pcre2_match_data_create(size, 
RegexContext::get_instance()->get_general_context());
-  }
+  debug_assert_message(match_data, "Failed to allocate pcre2 match data from 
custom context");
 
   _MatchData::set(_match_data, match_data);
 }
@@ -152,8 +147,23 @@ RegexMatches::malloc(size_t size, void *caller)
     return ptr;
   }
 
-  // return nullptr if buffer is too small
-  return nullptr;
+  return ::malloc(size);
+}
+
+void
+RegexMatches::free(void *p, void *caller)
+{
+  auto *matches = static_cast<RegexMatches *>(caller);
+
+  // Call free for any p outside _buffer
+  // If the pcre2 context requests more data than fits in our builtin buffer, 
we will call malloc
+  // to fulfil that request.
+  // !his checks for any pointers outside of our buffer in order to free that 
memory up.
+  //
+  // nullptr is outside of our buffer, but its ok to call ::free with nullptr.
+  if (!(p >= matches->_buffer && p < matches->_buffer + 
sizeof(matches->_buffer))) {
+    ::free(p);
+  }
 }
 
 //----------------------------------------------------------------------------

Reply via email to