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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9efc018724 header_rewrite fix storage lifetime for LAST-CAPTURE 
(#12809)
9efc018724 is described below

commit 9efc018724def2c1a0e1fe5129bb04c79f53bcf0
Author: Chris McFarlen <[email protected]>
AuthorDate: Thu Jan 15 14:34:43 2026 -0600

    header_rewrite fix storage lifetime for LAST-CAPTURE (#12809)
    
    * Use a class member variable to hold regex match
    
    * Use regex subject storage in Resources
    
    * rename extended struct
---
 plugins/header_rewrite/conditions.cc |  4 ++--
 plugins/header_rewrite/matcher.h     |  2 +-
 plugins/header_rewrite/resources.h   | 26 ++++++++++++++++++++++++--
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/plugins/header_rewrite/conditions.cc 
b/plugins/header_rewrite/conditions.cc
index 7b0ea0d076..19c7f3dbdf 100644
--- a/plugins/header_rewrite/conditions.cc
+++ b/plugins/header_rewrite/conditions.cc
@@ -1732,8 +1732,8 @@ ConditionLastCapture::set_qualifier(const std::string &q)
 void
 ConditionLastCapture::append_value(std::string &s, const Resources &res)
 {
-  if (res.matches.size() > _ix) {
-    s.append(res.matches[_ix]);
+  if (res.matches().size() > _ix) {
+    s.append(res.matches()[_ix]);
     Dbg(pi_dbg_ctl, "Evaluating LAST-CAPTURE(%d)", _ix);
   }
 }
diff --git a/plugins/header_rewrite/matcher.h b/plugins/header_rewrite/matcher.h
index dc8bf80380..1f4b52e143 100644
--- a/plugins/header_rewrite/matcher.h
+++ b/plugins/header_rewrite/matcher.h
@@ -364,7 +364,7 @@ private:
     Dbg(pi_dbg_ctl, "Test regular expression against: %s (NOCASE = %s)", 
t.c_str(),
         has_modifier(_mods, CondModifiers::MOD_NOCASE) ? "true" : "false");
     const auto &re    = std::get<regexHelper>(_data);
-    int         count = re.regexMatch(t, const_cast<Resources &>(res).matches);
+    int         count = res.match(re, t);
 
     if (count > 0) {
       Dbg(pi_dbg_ctl, "Successfully found regular expression match");
diff --git a/plugins/header_rewrite/resources.h 
b/plugins/header_rewrite/resources.h
index 3e2d729278..ab59540f97 100644
--- a/plugins/header_rewrite/resources.h
+++ b/plugins/header_rewrite/resources.h
@@ -23,6 +23,7 @@
 
 #include <string>
 
+#include "regex_helper.h"
 #include "ts/ts.h"
 #include "ts/remap.h"
 
@@ -79,6 +80,22 @@ public:
     return _ready;
   }
 
+  int
+  match(const regexHelper &re, const std::string &s) const
+  {
+    // For last capture to work safely, this has to make a copy of the subject 
string
+    // so the matches results will point into that and avoid any lifetime 
issues with
+    // the passed in `s`
+    _extended_info.subject_storage = s;
+    return re.regexMatch(_extended_info.subject_storage, 
_extended_info.matches);
+  }
+
+  const RegexMatches &
+  matches() const
+  {
+    return _extended_info.matches;
+  }
+
   TSCont              contp          = nullptr;
   TSRemapRequestInfo *_rri           = nullptr;
   TSMBuffer           bufp           = nullptr;
@@ -95,8 +112,13 @@ public:
   TransactionState state; // Without cripts, txnp / ssnp goes here
 #endif
   TSHttpStatus resp_status = TS_HTTP_STATUS_NONE;
-  RegexMatches matches;
-  bool         changed_url = false;
+
+  struct LifetimeExtension {
+    std::string  subject_storage;
+    RegexMatches matches;
+  };
+  bool                      changed_url = false;
+  mutable LifetimeExtension _extended_info;
 
 private:
   void

Reply via email to