Control: tags -1 + patch Please find attached a patch; build-tested only.
Description: Port to PCRE2. Bug-Debian: https://bugs.debian.org/999919 Bug: https://github.com/ZoneMinder/zoneminder/issues/3384 Author: Yavor Doganov <ya...@gnu.org> Forwarded: no Last-Update: 2023-12-22 ---
--- zoneminder-1.36.33+dfsg1.orig/CMakeLists.txt +++ zoneminder-1.36.33+dfsg1/CMakeLists.txt @@ -396,17 +396,17 @@ endif() # pcre (using find_library and find_path) -find_library(PCRE_LIBRARIES pcre) +find_library(PCRE_LIBRARIES pcre2-8) if(PCRE_LIBRARIES) set(HAVE_LIBPCRE 1) list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}") - find_path(PCRE_INCLUDE_DIR pcre.h) + find_path(PCRE_INCLUDE_DIR pcre2.h) if(PCRE_INCLUDE_DIR) include_directories("${PCRE_INCLUDE_DIR}") set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}") endif() mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR) - check_include_file("pcre.h" HAVE_PCRE_H) + check_include_file("pcre2.h" HAVE_PCRE2_H -DPCRE2_CODE_UNIT_WIDTH=8) set(optlibsfound "${optlibsfound} PCRE") else() set(optlibsnotfound "${optlibsnotfound} PCRE") --- zoneminder-1.36.33+dfsg1.orig/src/zm_regexp.cpp +++ zoneminder-1.36.33+dfsg1/src/zm_regexp.cpp @@ -24,25 +24,20 @@ #if HAVE_LIBPCRE -RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( nullptr ), match_lengths( nullptr ), match_valid( nullptr ) +RegExpr::RegExpr( const char *pattern, uint32_t flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( nullptr ), match_lengths( nullptr ), match_valid( nullptr ) { - const char *errstr; - int erroffset = 0; - if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) ) + char errstr[120]; + int err; + PCRE2_SIZE erroffset; + if ( !(regex = pcre2_compile( (PCRE2_SPTR)pattern, strlen( pattern ), flags, &err, &erroffset, NULL )) ) { - Panic( "pcre_compile(%s): %s at %d", pattern, errstr, erroffset ); - } - - regextra = pcre_study( regex, 0, &errstr ); - if ( errstr ) - { - Panic( "pcre_study(%s): %s", pattern, errstr ); + pcre2_get_error_message( err, (PCRE2_UCHAR *)errstr, sizeof(errstr) ); + Panic( "pcre2_compile(%s): %s at %zu", pattern, errstr, erroffset ); } if ( (ok = (bool)regex) ) { - match_vectors = new int[3*max_matches]; - memset( match_vectors, 0, sizeof(*match_vectors)*3*max_matches ); + match_data = pcre2_match_data_create( 3*max_matches, NULL ); match_buffers = new char *[max_matches]; memset( match_buffers, 0, sizeof(*match_buffers)*max_matches ); match_lengths = new int[max_matches]; @@ -68,18 +63,20 @@ delete[] match_valid; delete[] match_lengths; delete[] match_buffers; - delete[] match_vectors; + pcre2_match_data_free( match_data ); + pcre2_code_free( regex ); } -int RegExpr::Match( const char *subject_string, int subject_length, int flags ) +int RegExpr::Match( const char *subject_string, PCRE2_SIZE subject_length, uint32_t flags ) { match_string = subject_string; - n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches ); + n_matches = pcre2_match( regex, (PCRE2_SPTR)subject_string, subject_length, 0, flags, match_data, NULL ); + match_vectors = pcre2_get_ovector_pointer( match_data ); if ( n_matches <= 0 ) { - if ( n_matches < PCRE_ERROR_NOMATCH ) + if ( n_matches != PCRE2_ERROR_NOMATCH ) { Error( "Error %d executing regular expression", n_matches ); } @@ -101,7 +98,7 @@ } if ( !match_valid[match_index] ) { - int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index]; + int match_len = (int)(match_vectors[(2*match_index)+1]-match_vectors[2*match_index]); if ( match_lengths[match_index] < (match_len+1) ) { delete[] match_buffers[match_index]; @@ -121,7 +118,7 @@ { return( 0 ); } - return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] ); + return( (int)(match_vectors[(2*match_index)+1]-match_vectors[2*match_index]) ); } #endif // HAVE_LIBPCRE --- zoneminder-1.36.33+dfsg1.orig/src/zm_regexp.h +++ zoneminder-1.36.33+dfsg1/src/zm_regexp.h @@ -24,21 +24,20 @@ #if HAVE_LIBPCRE -#if HAVE_PCRE_H -#include <pcre.h> -#elif HAVE_PCRE_PCRE_H -#include <pcre/pcre.h> +#if HAVE_PCRE2_H +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #else -#error Unable to locate pcre.h, please do 'locate pcre.h' and report location to zoneminder.com +#error Unable to locate pcre2.h, please do 'locate pcre2.h' and report location to zoneminder.com #endif class RegExpr { protected: - pcre *regex; - pcre_extra *regextra; + pcre2_code *regex; + pcre2_match_data *match_data; int max_matches; - int *match_vectors; + PCRE2_SIZE *match_vectors; mutable char **match_buffers; int *match_lengths; bool *match_valid; @@ -51,11 +50,11 @@ bool ok; public: - explicit RegExpr( const char *pattern, int cflags=0, int p_max_matches=32 ); + explicit RegExpr( const char *pattern, uint32_t cflags=0, int p_max_matches=32 ); ~RegExpr(); bool Ok() const { return( ok ); } int MatchCount() const { return( n_matches ); } - int Match( const char *subject_string, int subject_length, int flags=0 ); + int Match( const char *subject_string, PCRE2_SIZE subject_length, uint32_t flags=0 ); const char *MatchString( int match_index ) const; int MatchLength( int match_index ) const; }; --- zoneminder-1.36.33+dfsg1.orig/src/zm_remote_camera_http.cpp +++ zoneminder-1.36.33+dfsg1/src/zm_remote_camera_http.cpp @@ -128,15 +128,15 @@ #if HAVE_LIBPCRE if ( method == REGEXP ) { if ( !header_expr ) - header_expr = new RegExpr("^(.+?\r?\n\r?\n)", PCRE_DOTALL); + header_expr = new RegExpr("^(.+?\r?\n\r?\n)", PCRE2_DOTALL); if ( !status_expr ) - status_expr = new RegExpr("^HTTP/(1\\.[01]) +([0-9]+) +(.+?)\r?\n", PCRE_CASELESS); + status_expr = new RegExpr("^HTTP/(1\\.[01]) +([0-9]+) +(.+?)\r?\n", PCRE2_CASELESS); if ( !connection_expr ) - connection_expr = new RegExpr("Connection: ?(.+?)\r?\n", PCRE_CASELESS); + connection_expr = new RegExpr("Connection: ?(.+?)\r?\n", PCRE2_CASELESS); if ( !content_length_expr ) - content_length_expr = new RegExpr("Content-length: ?([0-9]+)\r?\n", PCRE_CASELESS); + content_length_expr = new RegExpr("Content-length: ?([0-9]+)\r?\n", PCRE2_CASELESS); if ( !content_type_expr ) - content_type_expr = new RegExpr("Content-type: ?(.+?)(?:; ?boundary=\x22?(.+?)\x22?)?\r?\n", PCRE_CASELESS); + content_type_expr = new RegExpr("Content-type: ?(.+?)(?:; ?boundary=\x22?(.+?)\x22?)?\r?\n", PCRE2_CASELESS); } #endif } // end void RemoteCameraHttp::Initialise() @@ -455,7 +455,7 @@ if ( !subheader_expr ) { char subheader_pattern[256] = ""; snprintf( subheader_pattern, sizeof(subheader_pattern), "^((?:\r?\n){0,2}?(?:--)?%s\r?\n.+?\r?\n\r?\n)", content_boundary ); - subheader_expr = new RegExpr( subheader_pattern, PCRE_DOTALL ); + subheader_expr = new RegExpr( subheader_pattern, PCRE2_DOTALL ); } if ( subheader_expr->Match( (char *)buffer, (int)buffer ) == 2 ) { subheader = subheader_expr->MatchString( 1 ); @@ -463,14 +463,14 @@ Debug( 4, "Captured subheader (%d bytes):'%s'", subheader_len, subheader ); if ( !subcontent_length_expr ) - subcontent_length_expr = new RegExpr( "Content-length: ?([0-9]+)\r?\n", PCRE_CASELESS ); + subcontent_length_expr = new RegExpr( "Content-length: ?([0-9]+)\r?\n", PCRE2_CASELESS ); if ( subcontent_length_expr->Match( subheader, subheader_len ) == 2 ) { content_length = atoi( subcontent_length_expr->MatchString( 1 ) ); Debug( 3, "Got subcontent length '%d'", content_length ); } if ( !subcontent_type_expr ) - subcontent_type_expr = new RegExpr( "Content-type: ?(.+?)\r?\n", PCRE_CASELESS ); + subcontent_type_expr = new RegExpr( "Content-type: ?(.+?)\r?\n", PCRE2_CASELESS ); if ( subcontent_type_expr->Match( subheader, subheader_len ) == 2 ) { content_type = subcontent_type_expr->MatchString( 1 ); Debug( 3, "Got subcontent type '%s'", content_type ); @@ -534,7 +534,7 @@ if (!content_expr) { char content_pattern[256] = ""; snprintf(content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary); - content_expr = new RegExpr(content_pattern, PCRE_DOTALL); + content_expr = new RegExpr(content_pattern, PCRE2_DOTALL); } if (content_expr->Match( buffer, buffer.size()) == 2) { content_length = content_expr->MatchLength( 1 ); --- zoneminder-1.36.33+dfsg1.orig/zoneminder-config.cmake +++ zoneminder-1.36.33+dfsg1/zoneminder-config.cmake @@ -34,7 +34,7 @@ #cmakedefine HAVE_LIBPTHREAD 1 #cmakedefine HAVE_PTHREAD_H #cmakedefine HAVE_LIBPCRE 1 -#cmakedefine HAVE_PCRE_H 1 +#cmakedefine HAVE_PCRE2_H 1 #cmakedefine HAVE_LIBGCRYPT 1 #cmakedefine HAVE_GCRYPT_H 1 #cmakedefine HAVE_LIBGNUTLS 1