From 6875e8ff853d7827b7e9bba582ea6a291c8a2ea2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:13:52 +0000 Subject: [PATCH 1/3] Initial plan From d54e632e64c2bf9e6c2a1475479a173ce7efda12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:25:02 +0000 Subject: [PATCH 2/3] Migrate from PCRE to PCRE2 API Co-authored-by: djw8605 <79268+djw8605@users.noreply.github.com> --- CMakeLists.txt | 6 ++--- cmake/FindPcre2.cmake | 18 +++++++++++++ src/XrdCmsTfc.cc | 61 +++++++++++++++++++++++++------------------ src/XrdCmsTfc.hh | 7 ++--- 4 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 cmake/FindPcre2.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index aaacdac..8f9545c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ) find_package( Xrootd REQUIRED ) find_package( XercesC REQUIRED ) -find_package( Pcre REQUIRED ) +find_package( Pcre2 REQUIRED ) if( CMAKE_COMPILER_IS_GNUCXX ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror" ) @@ -17,10 +17,10 @@ if( CMAKE_COMPILER_IS_GNUCC ) endif() include_directories( "${PROJECT_SOURCE_DIR}" "${XROOTD_INCLUDES}" -"${XERCES_INCLUDES}" "${PCRE_INCLUDES}" ) +"${XERCES_INCLUDES}" "${PCRE2_INCLUDES}" ) add_library( XrdCmsTfc MODULE src/XrdCmsTfc.cc src/XrdCmsTfc.hh ) -target_link_libraries(XrdCmsTfc ${XROOTD_UTILS} ${XERCES_LIB} ${PCRE_LIB}) +target_link_libraries(XrdCmsTfc ${XROOTD_UTILS} ${XERCES_LIB} ${PCRE2_LIB}) if (NOT DEFINED CMAKE_INSTALL_LIBDIR) SET(CMAKE_INSTALL_LIBDIR "lib") diff --git a/cmake/FindPcre2.cmake b/cmake/FindPcre2.cmake new file mode 100644 index 0000000..cdfe07a --- /dev/null +++ b/cmake/FindPcre2.cmake @@ -0,0 +1,18 @@ +FIND_PATH(PCRE2_INCLUDES pcre2.h + HINTS + ${PCRE2_INCLUDE_DIR} + $ENV{PCRE2_INCLUDE_DIR} + /usr + PATH_SUFFIXES include +) + +FIND_LIBRARY(PCRE2_LIB pcre2-8 + HINTS + ${PCRE2_LIB_DIR} + $ENV{PCRE2_LIB_DIR} + /usr + PATH_SUFFIXES lib +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pcre2 DEFAULT_MSG PCRE2_LIB PCRE2_INCLUDES) \ No newline at end of file diff --git a/src/XrdCmsTfc.cc b/src/XrdCmsTfc.cc index 04062f1..ea981c0 100644 --- a/src/XrdCmsTfc.cc +++ b/src/XrdCmsTfc.cc @@ -94,7 +94,9 @@ void XrdCmsTfc::TrivialFileCatalog::freeProtocolRules(ProtocolRules protRules) { Rules rules = (*it).second; for (it2 = rules.begin(); it2 != rules.end(); it2++) { if (it2->pathMatch != NULL) - pcre_free(it2->pathMatch); + pcre2_code_free(it2->pathMatch); + if (it2->destinationMatch != NULL) + pcre2_code_free(it2->destinationMatch); } } } @@ -138,25 +140,25 @@ XrdCmsTfc::TrivialFileCatalog::parseRule (DOMNode *ruleNode, = _toChar (ruleElement->getAttribute (_toDOMS ("chain"))); Rule rule; - const char *error; - int erroffset; + int errornumber; + PCRE2_SIZE erroroffset; rule.pathMatch = NULL; rule.pathMatchStr = pathMatchRegexp; rule.destinationMatch = NULL; rule.destinationMatchStr = destinationMatchRegexp; - rule.pathMatch = pcre_compile(pathMatchRegexp, 0, &error, &erroffset, NULL); + rule.pathMatch = pcre2_compile((PCRE2_SPTR)pathMatchRegexp, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL); if (rule.pathMatch == NULL) { char *err = (char *)malloc(BUFFSIZE*sizeof(char)); - snprintf(err, BUFFSIZE, "PCRE compilation failed at offset %d: %s", erroffset, error); + snprintf(err, BUFFSIZE, "PCRE2 compilation failed at offset %lu: %d", (unsigned long)erroroffset, errornumber); eDest->Say(err); free(err); return XRDCMSTFC_ERR_PARSERULE; } - rule.destinationMatch = pcre_compile(destinationMatchRegexp, 0, &error, &erroffset, NULL); + rule.destinationMatch = pcre2_compile((PCRE2_SPTR)destinationMatchRegexp, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL); if (rule.destinationMatch == NULL) { char *err = (char *)malloc(BUFFSIZE*sizeof(char)); - snprintf(err, BUFFSIZE, "PCRE compilation failed at offset %d: %s", erroffset, error); + snprintf(err, BUFFSIZE, "PCRE2 compilation failed at offset %lu: %d", (unsigned long)erroroffset, errornumber); eDest->Say(err); free(err); return XRDCMSTFC_ERR_PARSERULE; @@ -328,17 +330,18 @@ int XrdCmsTfc::TrivialFileCatalog::lfn2rfn(const char *lfn, char *buff, int blen } -std::string replace(const std::string inputString, pcre * re, std::string replacementString) { +std::string replace(const std::string inputString, pcre2_code * re, std::string replacementString) { - int ovector[OVECCOUNT], rc; + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL); std::string result; - rc = pcre_exec(re, NULL, inputString.c_str(), inputString.length(), 0, 0, - ovector, OVECCOUNT); + int rc = pcre2_match(re, (PCRE2_SPTR)inputString.c_str(), inputString.length(), 0, 0, match_data, NULL); if (rc <= 0) { + pcre2_match_data_free(match_data); return ""; } + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); int substring_end = 0, substring_begin; for (int i = 0; i < rc; i++) { substring_begin = ovector[2*i]; @@ -346,10 +349,11 @@ std::string replace(const std::string inputString, pcre * re, std::string replac substring_end = ovector[2*i+1] + substring_begin; } + pcre2_match_data_free(match_data); return result; } -std::string replaceWithRegexp (const int ovector[OVECCOUNT], const int rc, +std::string replaceWithRegexp (const PCRE2_SIZE ovector[], const int rc, const std::string inputString, const std::string outputFormat) { @@ -357,8 +361,8 @@ std::string replaceWithRegexp (const int ovector[OVECCOUNT], const int rc, char buffer[11]; std::string result = outputFormat; - int substring_length; - int substring_begin; + PCRE2_SIZE substring_length; + PCRE2_SIZE substring_begin; for (int i = 1; i < rc; @@ -373,19 +377,19 @@ std::string replaceWithRegexp (const int ovector[OVECCOUNT], const int rc, substring_length = ovector[2*i+1] - substring_begin; std::string matchResult = inputString.substr(substring_begin, substring_length); - const char *error; - int erroffset; - pcre * substitutionToken = pcre_compile(variableRegexp.c_str(), - 0, &error, &erroffset, NULL); + int errornumber; + PCRE2_SIZE erroroffset; + pcre2_code * substitutionToken = pcre2_compile((PCRE2_SPTR)variableRegexp.c_str(), + PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL); if (substitutionToken == NULL) { - pcre_free(substitutionToken); + pcre2_code_free(substitutionToken); return ""; } //std::cerr << "Current match: " << matchResult << std::endl; result = replace(result, substitutionToken, matchResult); - pcre_free(substitutionToken); + pcre2_code_free(substitutionToken); } return result; } @@ -411,17 +415,21 @@ XrdCmsTfc::TrivialFileCatalog::applyRules (const ProtocolRules& protocolRules, i != rules.end (); i++) { - int ovector[OVECCOUNT]; + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(i->destinationMatch, NULL); int rc=0; - rc = pcre_exec(i->destinationMatch, NULL, destination.c_str(), destination.length(), 0, PCRE_ANCHORED, ovector, OVECCOUNT); + rc = pcre2_match(i->destinationMatch, (PCRE2_SPTR)destination.c_str(), destination.length(), 0, PCRE2_ANCHORED, match_data, NULL); if (rc < 0) { + pcre2_match_data_free(match_data); continue; } else { //std::cerr << "Destination did match; my destination " << destination << ", regexp: " << i->destinationMatchStr << std::endl; } - rc = pcre_exec(i->pathMatch, NULL, name.c_str(), name.length(), 0, PCRE_ANCHORED, ovector, OVECCOUNT); + pcre2_match_data_free(match_data); + match_data = pcre2_match_data_create_from_pattern(i->pathMatch, NULL); + rc = pcre2_match(i->pathMatch, (PCRE2_SPTR)name.c_str(), name.length(), 0, PCRE2_ANCHORED, match_data, NULL); if (rc < 0) { + pcre2_match_data_free(match_data); continue; } else { //std::cerr << "Path did match; my path " << name << ", regexp: " << i->pathMatchStr << std::endl; @@ -438,10 +446,12 @@ XrdCmsTfc::TrivialFileCatalog::applyRules (const ProtocolRules& protocolRules, //std::cerr << "Not chaining another rule!" << std::endl; } - rc = pcre_exec(i->pathMatch, NULL, name.c_str(), name.length(), 0, PCRE_ANCHORED, ovector, - OVECCOUNT); + pcre2_match_data_free(match_data); + match_data = pcre2_match_data_create_from_pattern(i->pathMatch, NULL); + rc = pcre2_match(i->pathMatch, (PCRE2_SPTR)name.c_str(), name.length(), 0, PCRE2_ANCHORED, match_data, NULL); if (rc >= 0) { + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); name = replaceWithRegexp(ovector, rc, name, i->result); } else { //std::cerr << "No replacements necessary." << std::endl; @@ -453,6 +463,7 @@ XrdCmsTfc::TrivialFileCatalog::applyRules (const ProtocolRules& protocolRules, applyRules (protocolRules, chain, destination, direct, name); } //std::cerr << "Result " << name << std::endl; + pcre2_match_data_free(match_data); return name; } return ""; diff --git a/src/XrdCmsTfc.hh b/src/XrdCmsTfc.hh index 0237ace..b778943 100644 --- a/src/XrdCmsTfc.hh +++ b/src/XrdCmsTfc.hh @@ -4,7 +4,8 @@ #include "XrdOuc/XrdOucName2Name.hh" #include "XrdSys/XrdSysError.hh" -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #include #include @@ -48,9 +49,9 @@ public: private: typedef struct { - pcre *pathMatch; + pcre2_code *pathMatch; std::string pathMatchStr; - pcre *destinationMatch; + pcre2_code *destinationMatch; std::string destinationMatchStr; std::string result; std::string chain; From cbb536fba633dc5bb60c40ad206a0a56814b4e85 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:28:57 +0000 Subject: [PATCH 3/3] Remove obsolete FindPcre.cmake and complete PCRE2 migration Co-authored-by: djw8605 <79268+djw8605@users.noreply.github.com> --- cmake/FindPcre.cmake | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 cmake/FindPcre.cmake diff --git a/cmake/FindPcre.cmake b/cmake/FindPcre.cmake deleted file mode 100644 index ce434f3..0000000 --- a/cmake/FindPcre.cmake +++ /dev/null @@ -1,20 +0,0 @@ - -FIND_PATH(PCRE_INCLUDES pcre.h - HINTS - ${PCRE_INCLUDE_DIR} - $ENV{PCRE_INCLUDE_DIR} - /usr - PATH_SUFFIXES include -) - -FIND_LIBRARY(PCRE_LIB pcre - HINTS - ${PCRE_LIB_DIR} - $ENV{PCRE_LIB_DIR} - /usr - PATH_SUFFIXES lib -) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pcre DEFAULT_MSG PCRE_LIB PCRE_INCLUDES) -