diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1bbf514c9..98d6982ab 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -61,7 +61,7 @@ jobs: sudo apt-get update sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev libjwt-gnutls-dev libavdevice-dev sudo apt-get install libbz2-dev libcurl4-gnutls-dev libjpeg-turbo8-dev libturbojpeg0-dev - sudo apt-get install default-libmysqlclient-dev libpcre2-dev libpolkit-gobject-1-dev libv4l-dev libvlc-dev + sudo apt-get install default-libmysqlclient-dev libpcre3-dev libpolkit-gobject-1-dev libv4l-dev libvlc-dev sudo apt-get install libdate-manip-perl libdbd-mysql-perl libphp-serialization-perl libsys-mmap-perl sudo apt-get install libwww-perl libdata-uuid-perl libssl-dev libcrypt-eksblowfish-perl libdata-entropy-perl diff --git a/CMakeLists.txt b/CMakeLists.txt index be4b2bd74..ba8464b59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,7 @@ set(ZM_ONVIF "ON" CACHE BOOL "Set to ON to enable basic ONVIF support. This is EXPERIMENTAL and may not work with all cameras claiming to be ONVIF compliant. default: ON") set(ZM_NO_PCRE "OFF" CACHE BOOL - "Set to ON to skip libpcre2 checks and force building ZM without libpcre2. default: OFF") + "Set to ON to skip libpcre3 checks and force building ZM without libpcre3. default: OFF") set(ZM_NO_RTSPSERVER "OFF" CACHE BOOL "Set to ON to skip building ZM with rtsp server support. default: OFF") set(ZM_PERL_MM_PARMS INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 CACHE STRING @@ -422,17 +422,17 @@ endif() # Do not check for cURL if ZM_NO_CURL is on if(NOT ZM_NO_PRCE) # pcre (using find_library and find_path) - find_library(PCRE_LIBRARIES pcre2-8) + find_library(PCRE_LIBRARIES pcre) if(PCRE_LIBRARIES) set(HAVE_LIBPCRE 1) list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}") - find_path(PCRE_INCLUDE_DIR pcre2.h) + find_path(PCRE_INCLUDE_DIR pcre.h) if(PCRE_INCLUDE_DIR) include_directories("${PCRE_INCLUDE_DIR}") set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}") - set(HAVE_PCRE_H ON) endif() mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR) + check_include_file("pcre.h" HAVE_PCRE_H) set(optlibsfound "${optlibsfound} PCRE") else() set(optlibsnotfound "${optlibsnotfound} PCRE") diff --git a/distros/beowulf/control b/distros/beowulf/control index fbb35a0f3..50d25a0c4 100644 --- a/distros/beowulf/control +++ b/distros/beowulf/control @@ -16,7 +16,7 @@ Build-Depends: debhelper, sphinx-doc, dh-linktree, dh-apache2 ,libcurl4-gnutls-dev ,libturbojpeg0-dev ,default-libmysqlclient-dev | libmysqlclient-dev | libmariadbclient-dev-compat - ,libpcre2-dev + ,libpcre3-dev ,libpolkit-gobject-1-dev ,libv4l-dev [!hurd-any] ,libvlc-dev @@ -72,7 +72,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,policykit-1 ,rsyslog | system-log-daemon ,zip - ,libpcre2 + ,libpcre3 ,libcrypt-eksblowfish-perl ,libdata-entropy-perl Recommends: ${misc:Recommends} diff --git a/distros/ubuntu1504_cmake_split_packages/control b/distros/ubuntu1504_cmake_split_packages/control index 0ee2d99ad..1345c39ee 100644 --- a/distros/ubuntu1504_cmake_split_packages/control +++ b/distros/ubuntu1504_cmake_split_packages/control @@ -7,7 +7,7 @@ Build-Depends: debhelper (>= 9), po-debconf (>= 1.0), autoconf, automake, libtoo , libmysqlclient-dev | libmariadbclient-dev, libdbd-mysql-perl , libdate-manip-perl, libwww-perl , libjpeg8-dev | libjpeg9-dev | libjpeg62-turbo-dev -, libpcre2-dev +, libpcre3-dev , libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev , libv4l-dev (>= 0.8.3) , libbz2-dev diff --git a/src/zm_regexp.cpp b/src/zm_regexp.cpp index 86900f68e..1541b31ef 100644 --- a/src/zm_regexp.cpp +++ b/src/zm_regexp.cpp @@ -26,27 +26,31 @@ 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 ) { - int errorcode; - PCRE2_SIZE erroffset = 0; - match_data = pcre2_match_data_create(max_matches, nullptr); - if ( !(regex = pcre2_compile( (PCRE2_SPTR8)pattern, strlen(pattern), flags, &errorcode, &erroffset, nullptr )) ) + const char *errstr; + int erroffset = 0; + if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) ) { - PCRE2_UCHAR buffer[256]; - pcre2_get_error_message(errorcode, buffer, sizeof(buffer)); - Panic( "pcre2_compile(%s): %s at %ld", pattern, buffer, erroffset ); + 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 ); } if ( (ok = (bool)regex) ) { + match_vectors = new int[3*max_matches]; + memset( match_vectors, 0, sizeof(*match_vectors)*3*max_matches ); match_buffers = new char *[max_matches]; memset( match_buffers, 0, sizeof(*match_buffers)*max_matches ); - match_lengths = new PCRE2_SIZE[max_matches]; + match_lengths = new int[max_matches]; memset( match_lengths, 0, sizeof(*match_lengths)*max_matches ); match_valid = new bool[max_matches]; memset( match_valid, 0, sizeof(*match_valid)*max_matches ); } else { - pcre2_match_data_free(match_data); - match_data = nullptr; + match_vectors = nullptr; } match_string = ""; n_matches = 0; @@ -64,22 +68,18 @@ RegExpr::~RegExpr() delete[] match_valid; delete[] match_lengths; delete[] match_buffers; - if ( match_data ) - { - pcre2_match_data_free(match_data); - } + delete[] match_vectors; } int RegExpr::Match( const char *subject_string, int subject_length, int flags ) { match_string = subject_string; - int rc = pcre2_match( regex, (PCRE2_SPTR)subject_string, subject_length, 0, flags, match_data, nullptr ); - n_matches = pcre2_get_ovector_count(match_data); + n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches ); - if ( rc < 0 || n_matches <= 0 ) + if ( n_matches <= 0 ) { - if ( rc <= PCRE2_ERROR_NOMATCH ) + if ( n_matches < PCRE_ERROR_NOMATCH ) { Error( "Error %d executing regular expression", n_matches ); } @@ -101,15 +101,14 @@ const char *RegExpr::MatchString( int match_index ) const } if ( !match_valid[match_index] ) { - PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data); - PCRE2_SIZE match_len = ovector[(2*match_index)+1]-ovector[2*match_index]; + int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index]; if ( match_lengths[match_index] < (match_len+1) ) { delete[] match_buffers[match_index]; match_buffers[match_index] = new char[match_len+1]; match_lengths[match_index] = match_len+1; } - memcpy( match_buffers[match_index], match_string+ovector[2*match_index], match_len ); + memcpy( match_buffers[match_index], match_string+match_vectors[2*match_index], match_len ); match_buffers[match_index][match_len] = '\0'; match_valid[match_index] = true; } @@ -122,8 +121,7 @@ int RegExpr::MatchLength( int match_index ) const { return( 0 ); } - PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data); - return( ovector[(2*match_index)+1]-ovector[2*match_index] ); + return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] ); } #endif // HAVE_LIBPCRE diff --git a/src/zm_regexp.h b/src/zm_regexp.h index d718cf7e9..9c9ec5675 100644 --- a/src/zm_regexp.h +++ b/src/zm_regexp.h @@ -23,28 +23,29 @@ #include "zm_config.h" #if HAVE_LIBPCRE -#define PCRE2_CODE_UNIT_WIDTH 8 + #if HAVE_PCRE_H -#include +#include #elif HAVE_PCRE_PCRE_H -#include +#include #else -#error Unable to locate pcre2.h, please do 'locate pcre2.h' and report location to zoneminder.com +#error Unable to locate pcre.h, please do 'locate pcre.h' and report location to zoneminder.com #endif class RegExpr { protected: - pcre2_code *regex{nullptr}; + pcre *regex; + pcre_extra *regextra; int max_matches; - pcre2_match_data *match_data{nullptr}; - mutable char **match_buffers{nullptr}; - PCRE2_SIZE *match_lengths{nullptr}; - bool *match_valid{nullptr}; + int *match_vectors; + mutable char **match_buffers; + int *match_lengths; + bool *match_valid; protected: - const char *match_string{nullptr}; - int32_t n_matches; + const char *match_string; + int n_matches; protected: bool ok; diff --git a/src/zm_remote_camera_http.cpp b/src/zm_remote_camera_http.cpp index 386a90cbe..f70b17fa8 100644 --- a/src/zm_remote_camera_http.cpp +++ b/src/zm_remote_camera_http.cpp @@ -132,15 +132,15 @@ void RemoteCameraHttp::Initialise() { #if HAVE_LIBPCRE if ( method == REGEXP ) { if ( !header_expr ) - header_expr = new RegExpr("^(.+?\r?\n\r?\n)", PCRE2_DOTALL); + header_expr = new RegExpr("^(.+?\r?\n\r?\n)", PCRE_DOTALL); if ( !status_expr ) - status_expr = new RegExpr("^HTTP/(1\\.[01]) +([0-9]+) +(.+?)\r?\n", PCRE2_CASELESS); + status_expr = new RegExpr("^HTTP/(1\\.[01]) +([0-9]+) +(.+?)\r?\n", PCRE_CASELESS); if ( !connection_expr ) - connection_expr = new RegExpr("Connection: ?(.+?)\r?\n", PCRE2_CASELESS); + connection_expr = new RegExpr("Connection: ?(.+?)\r?\n", PCRE_CASELESS); if ( !content_length_expr ) - content_length_expr = new RegExpr("Content-length: ?([0-9]+)\r?\n", PCRE2_CASELESS); + content_length_expr = new RegExpr("Content-length: ?([0-9]+)\r?\n", PCRE_CASELESS); if ( !content_type_expr ) - content_type_expr = new RegExpr("Content-type: ?(.+?)(?:; ?boundary=\x22?(.+?)\x22?)?\r?\n", PCRE2_CASELESS); + content_type_expr = new RegExpr("Content-type: ?(.+?)(?:; ?boundary=\x22?(.+?)\x22?)?\r?\n", PCRE_CASELESS); } #endif } // end void RemoteCameraHttp::Initialise() @@ -468,7 +468,7 @@ int RemoteCameraHttp::GetResponse() { 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, PCRE2_DOTALL ); + subheader_expr = new RegExpr( subheader_pattern, PCRE_DOTALL ); } if ( subheader_expr->Match( (char *)buffer, (int)buffer ) == 2 ) { subheader = subheader_expr->MatchString( 1 ); @@ -476,14 +476,14 @@ int RemoteCameraHttp::GetResponse() { 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", PCRE2_CASELESS ); + subcontent_length_expr = new RegExpr( "Content-length: ?([0-9]+)\r?\n", PCRE_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", PCRE2_CASELESS ); + subcontent_type_expr = new RegExpr( "Content-type: ?(.+?)\r?\n", PCRE_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 ); @@ -549,7 +549,7 @@ int RemoteCameraHttp::GetResponse() { 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, PCRE2_DOTALL); + content_expr = new RegExpr(content_pattern, PCRE_DOTALL); } if (content_expr->Match( buffer, buffer.size()) == 2) { content_length = content_expr->MatchLength( 1 );