regexp: port to pcre2

Update pcre usage to be compatible with pcre2.
pull/3824/head
David Aguilar 2024-02-14 09:47:09 +00:00
parent 3dd9bdc121
commit fd09feb5f4
7 changed files with 51 additions and 50 deletions

View File

@ -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 libpcre3-dev libpolkit-gobject-1-dev libv4l-dev libvlc-dev
sudo apt-get install default-libmysqlclient-dev libpcre2-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

View File

@ -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 libpcre3 checks and force building ZM without libpcre3. default: OFF")
"Set to ON to skip libpcre2 checks and force building ZM without libpcre2. 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 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}")
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")

View File

@ -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
,libpcre3-dev
,libpcre2-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
,libpcre3
,libpcre2
,libcrypt-eksblowfish-perl
,libdata-entropy-perl
Recommends: ${misc:Recommends}

View File

@ -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
, libpcre3-dev
, libpcre2-dev
, libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev
, libv4l-dev (>= 0.8.3)
, libbz2-dev

View File

@ -26,31 +26,27 @@
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 )
{
const char *errstr;
int erroffset = 0;
if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) )
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 )) )
{
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_UCHAR buffer[256];
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
Panic( "pcre2_compile(%s): %s at %ld", pattern, buffer, erroffset );
}
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 int[max_matches];
match_lengths = new PCRE2_SIZE[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 {
match_vectors = nullptr;
pcre2_match_data_free(match_data);
match_data = nullptr;
}
match_string = "";
n_matches = 0;
@ -68,18 +64,22 @@ RegExpr::~RegExpr()
delete[] match_valid;
delete[] match_lengths;
delete[] match_buffers;
delete[] match_vectors;
if ( match_data )
{
pcre2_match_data_free(match_data);
}
}
int RegExpr::Match( const char *subject_string, int subject_length, int flags )
{
match_string = subject_string;
n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches );
int rc = pcre2_match( regex, (PCRE2_SPTR)subject_string, subject_length, 0, flags, match_data, nullptr );
n_matches = pcre2_get_ovector_count(match_data);
if ( n_matches <= 0 )
if ( rc < 0 || n_matches <= 0 )
{
if ( n_matches < PCRE_ERROR_NOMATCH )
if ( rc <= PCRE2_ERROR_NOMATCH )
{
Error( "Error %d executing regular expression", n_matches );
}
@ -101,14 +101,15 @@ const char *RegExpr::MatchString( int match_index ) const
}
if ( !match_valid[match_index] )
{
int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index];
PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data);
PCRE2_SIZE match_len = ovector[(2*match_index)+1]-ovector[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+match_vectors[2*match_index], match_len );
memcpy( match_buffers[match_index], match_string+ovector[2*match_index], match_len );
match_buffers[match_index][match_len] = '\0';
match_valid[match_index] = true;
}
@ -121,7 +122,8 @@ int RegExpr::MatchLength( int match_index ) const
{
return( 0 );
}
return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] );
PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data);
return( ovector[(2*match_index)+1]-ovector[2*match_index] );
}
#endif // HAVE_LIBPCRE

View File

@ -23,29 +23,28 @@
#include "zm_config.h"
#if HAVE_LIBPCRE
#define PCRE2_CODE_UNIT_WIDTH 8
#if HAVE_PCRE_H
#include <pcre.h>
#include <pcre2.h>
#elif HAVE_PCRE_PCRE_H
#include <pcre/pcre.h>
#include <pcre/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{nullptr};
int max_matches;
int *match_vectors;
mutable char **match_buffers;
int *match_lengths;
bool *match_valid;
pcre2_match_data *match_data{nullptr};
mutable char **match_buffers{nullptr};
PCRE2_SIZE *match_lengths{nullptr};
bool *match_valid{nullptr};
protected:
const char *match_string;
int n_matches;
const char *match_string{nullptr};
int32_t n_matches;
protected:
bool ok;

View File

@ -132,15 +132,15 @@ void RemoteCameraHttp::Initialise() {
#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()
@ -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, PCRE_DOTALL );
subheader_expr = new RegExpr( subheader_pattern, PCRE2_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", 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 );
@ -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, PCRE_DOTALL);
content_expr = new RegExpr(content_pattern, PCRE2_DOTALL);
}
if (content_expr->Match( buffer, buffer.size()) == 2) {
content_length = content_expr->MatchLength( 1 );