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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new ece6229fbe Update header_rewrite to use Regex (#12573) (#12787)
ece6229fbe is described below

commit ece6229fbe4192873ae48a48ad9304dda7c6933d
Author: Chris McFarlen <[email protected]>
AuthorDate: Wed Jan 14 13:03:43 2026 -0600

    Update header_rewrite to use Regex (#12573) (#12787)
    
    * Update header_rewrite to use Regex
    
    * PR review
    
    * cast to int
    
    * also move dbg for failed regex compile.
    
    (cherry picked from commit a15669b7d60084f849de11be235bfcf8575f3d53)
---
 plugins/header_rewrite/CMakeLists.txt  |  2 +-
 plugins/header_rewrite/conditions.cc   |  7 ++-----
 plugins/header_rewrite/matcher.h       |  6 ++----
 plugins/header_rewrite/regex_helper.cc | 30 +++++++++---------------------
 plugins/header_rewrite/regex_helper.h  | 19 +++----------------
 plugins/header_rewrite/resources.cc    |  4 ----
 plugins/header_rewrite/resources.h     |  7 +++----
 7 files changed, 20 insertions(+), 55 deletions(-)

diff --git a/plugins/header_rewrite/CMakeLists.txt 
b/plugins/header_rewrite/CMakeLists.txt
index 7527a1efd3..89cf63d8a5 100644
--- a/plugins/header_rewrite/CMakeLists.txt
+++ b/plugins/header_rewrite/CMakeLists.txt
@@ -38,7 +38,7 @@ target_link_libraries(header_rewrite_parser PUBLIC 
libswoc::libswoc)
 
 target_link_libraries(
   header_rewrite
-  PRIVATE OpenSSL::Crypto PCRE::PCRE
+  PRIVATE OpenSSL::Crypto
   PUBLIC libswoc::libswoc
 )
 
diff --git a/plugins/header_rewrite/conditions.cc 
b/plugins/header_rewrite/conditions.cc
index 522a60bc69..9442c0ab56 100644
--- a/plugins/header_rewrite/conditions.cc
+++ b/plugins/header_rewrite/conditions.cc
@@ -1718,11 +1718,8 @@ ConditionLastCapture::set_qualifier(const std::string &q)
 void
 ConditionLastCapture::append_value(std::string &s, const Resources &res)
 {
-  if (res.ovector_ptr && res.ovector_count > _ix) {
-    int start = res.ovector[_ix * 2];
-    int end   = res.ovector[_ix * 2 + 1];
-
-    s.append(std::string_view(res.ovector_ptr).substr(start, (end - start)));
+  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 3406eb389e..891fb46a46 100644
--- a/plugins/header_rewrite/matcher.h
+++ b/plugins/header_rewrite/matcher.h
@@ -32,6 +32,7 @@
 #include "resources.h"
 #include "regex_helper.h"
 #include "lulu.h"
+#include "tsutil/Regex.h"
 
 // Possible operators that we support (at least partially)
 enum MatcherOps {
@@ -192,13 +193,10 @@ private:
   test_reg(const std::string &t, const Resources &res) const
   {
     Dbg(pi_dbg_ctl, "Test regular expression %s : %s (NOCASE = %d)", 
_data.c_str(), t.c_str(), static_cast<int>(_nocase));
-    int count = _reHelper.regexMatch(t.c_str(), t.length(), 
const_cast<Resources &>(res).ovector);
+    int count = _reHelper.regexMatch(t, const_cast<Resources &>(res).matches);
 
     if (count > 0) {
       Dbg(pi_dbg_ctl, "Successfully found regular expression match");
-      const_cast<Resources &>(res).ovector_ptr   = t.c_str();
-      const_cast<Resources &>(res).ovector_count = count;
-
       return true;
     }
 
diff --git a/plugins/header_rewrite/regex_helper.cc 
b/plugins/header_rewrite/regex_helper.cc
index de1e7f2ef9..d4b36c765f 100644
--- a/plugins/header_rewrite/regex_helper.cc
+++ b/plugins/header_rewrite/regex_helper.cc
@@ -17,39 +17,27 @@
 */
 #include "regex_helper.h"
 #include "lulu.h"
+#include "ts/ts.h"
+#include "tsutil/Regex.h"
 
 bool
 regexHelper::setRegexMatch(const std::string &s, bool nocase)
 {
-  const char *errorComp  = nullptr;
-  const char *errorStudy = nullptr;
-  int         erroffset;
+  std::string error;
+  int         errorOffset;
 
   regexString = s;
-  regex       = pcre_compile(regexString.c_str(), nocase ? PCRE_CASELESS : 0, 
&errorComp, &erroffset, nullptr);
 
-  if (regex == nullptr) {
-    return false;
-  }
-  regexExtra = pcre_study(regex, 0, &errorStudy);
-  if ((regexExtra == nullptr) && (errorStudy != nullptr)) {
-    return false;
-  }
-  if (pcre_fullinfo(regex, regexExtra, PCRE_INFO_CAPTURECOUNT, &regexCcount) 
!= 0) {
+  if (!regex.compile(regexString, error, errorOffset, nocase ? 
static_cast<int>(RE_CASE_INSENSITIVE) : 0)) {
+    TSError("[%s] Invalid regex: failed to precompile: %s (%s at %d)", 
PLUGIN_NAME, s.c_str(), error.c_str(), errorOffset);
+    Dbg(pi_dbg_ctl, "Invalid regex: failed to precompile: %s (%s at %d)", 
s.c_str(), error.c_str(), errorOffset);
     return false;
   }
   return true;
 }
 
 int
-regexHelper::regexMatch(const char *str, int len, int ovector[]) const
+regexHelper::regexMatch(std::string_view subject, RegexMatches &matches) const
 {
-  return pcre_exec(regex,      // the compiled pattern
-                   regexExtra, // Extra data from study (maybe)
-                   str,        // the subject std::string
-                   len,        // the length of the subject
-                   0,          // start at offset 0 in the subject
-                   0,          // default options
-                   ovector,    // output vector for substring information
-                   OVECCOUNT); // number of elements in the output vector
+  return regex.exec(subject, matches);
 };
diff --git a/plugins/header_rewrite/regex_helper.h 
b/plugins/header_rewrite/regex_helper.h
index 98a69c0f2a..abe1b01941 100644
--- a/plugins/header_rewrite/regex_helper.h
+++ b/plugins/header_rewrite/regex_helper.h
@@ -18,30 +18,17 @@
 #pragma once
 
 #include "tscore/ink_defs.h"
-
-#ifdef HAVE_PCRE_PCRE_H
-#include <pcre/pcre.h>
-#else
-#include <pcre.h>
-#endif
+#include "tsutil/Regex.h"
 
 #include <string>
 
 class regexHelper
 {
 public:
-  ~regexHelper()
-  {
-    pcre_free(regex);
-    pcre_free(regexExtra);
-  }
-
   bool setRegexMatch(const std::string &s, bool nocase = false);
-  int  regexMatch(const char *, int, int ovector[]) const;
+  int  regexMatch(std::string_view subject, RegexMatches &matches) const;
 
 private:
   std::string regexString;
-  pcre       *regex       = nullptr;
-  pcre_extra *regexExtra  = nullptr;
-  int         regexCcount = 0;
+  Regex       regex;
 };
diff --git a/plugins/header_rewrite/resources.cc 
b/plugins/header_rewrite/resources.cc
index 7f5a755fc8..025fe390e4 100644
--- a/plugins/header_rewrite/resources.cc
+++ b/plugins/header_rewrite/resources.cc
@@ -34,10 +34,6 @@ Resources::gather(const ResourceIDs ids, TSHttpHookID hook)
 {
   Dbg(pi_dbg_ctl, "Building resources, hook=%s", TSHttpHookNameLookup(hook));
 
-  // Clear the capture groups just in case
-  ovector_count = 0;
-  ovector_ptr   = nullptr;
-
   Dbg(pi_dbg_ctl, "Gathering resources for hook %s with IDs %d", 
TSHttpHookNameLookup(hook), ids);
 
   // If we need the client request headers, make sure it's also available in 
the client vars.
diff --git a/plugins/header_rewrite/resources.h 
b/plugins/header_rewrite/resources.h
index a56c808dee..3e2d729278 100644
--- a/plugins/header_rewrite/resources.h
+++ b/plugins/header_rewrite/resources.h
@@ -27,6 +27,7 @@
 #include "ts/remap.h"
 
 #include "lulu.h"
+#include "tsutil/Regex.h"
 
 #if TS_HAS_CRIPTS
 #include "cripts/Certs.hpp"
@@ -93,11 +94,9 @@ public:
 #else
   TransactionState state; // Without cripts, txnp / ssnp goes here
 #endif
-  const char  *ovector_ptr = nullptr;
   TSHttpStatus resp_status = TS_HTTP_STATUS_NONE;
-  int          ovector[OVECCOUNT];
-  int          ovector_count = 0;
-  bool         changed_url   = false;
+  RegexMatches matches;
+  bool         changed_url = false;
 
 private:
   void

Reply via email to