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

Reply via email to