diff --git a/plugins/header_rewrite/CMakeLists.txt b/plugins/header_rewrite/CMakeLists.txt index 7527a1efd31..89cf63d8a5e 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 522a60bc692..9442c0ab56e 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 3406eb389e4..891fb46a46e 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 @@ template class Matchers : public Matcher 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(_nocase)); - int count = _reHelper.regexMatch(t.c_str(), t.length(), const_cast(res).ovector); + int count = _reHelper.regexMatch(t, const_cast(res).matches); if (count > 0) { Dbg(pi_dbg_ctl, "Successfully found regular expression match"); - const_cast(res).ovector_ptr = t.c_str(); - const_cast(res).ovector_count = count; - return true; } diff --git a/plugins/header_rewrite/regex_helper.cc b/plugins/header_rewrite/regex_helper.cc index de1e7f2ef90..d4b36c765f2 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, ®exCcount) != 0) { + if (!regex.compile(regexString, error, errorOffset, nocase ? static_cast(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 98a69c0f2a2..abe1b019410 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 -#else -#include -#endif +#include "tsutil/Regex.h" #include 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 7f5a755fc8f..025fe390e49 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 a56c808deef..3e2d729278b 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 @@ class Resources #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