Skip to content

Commit 4704813

Browse files
authored
Merge pull request #2015 from evgenyz/pcre2
PCRE2
2 parents ed91feb + f239fd8 commit 4704813

35 files changed

+699
-397
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ jobs:
3434
- name: Install Deps
3535
run: |
3636
sudo apt-get update
37-
sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libyaml-dev libapt-pkg-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock
37+
sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libpcre2-dev libyaml-dev libapt-pkg-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock
3838
sudo apt-get -y remove rpm
3939
4040
# Runs a set of commands using the runners shell
4141
- name: Build
4242
working-directory: ./build
4343
run: |
44-
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ../
44+
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_PCRE2=True ../
4545
make all
4646
4747
- name: Test
@@ -57,15 +57,15 @@ jobs:
5757
image: fedora:latest
5858
steps:
5959
- name: Install Deps
60-
run: dnf install -y cmake git dbus-devel GConf2-devel libacl-devel libblkid-devel libcap-devel libcurl-devel libgcrypt-devel libselinux-devel libxml2-devel libxslt-devel libattr-devel make openldap-devel pcre-devel perl-XML-Parser perl-XML-XPath perl-devel python3-devel python3-dbusmock rpm-devel swig bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel hostname bzip2 lua rpm-build which strace apt-devel
60+
run: dnf install -y cmake git dbus-devel GConf2-devel libacl-devel libblkid-devel libcap-devel libcurl-devel libgcrypt-devel libselinux-devel libxml2-devel libxslt-devel libattr-devel make openldap-devel pcre2-devel perl-XML-Parser perl-XML-XPath perl-devel python3-devel python3-dbusmock rpm-devel swig bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel hostname bzip2 lua rpm-build which strace apt-devel
6161
- name: Checkout
6262
uses: actions/checkout@v3
6363
with:
6464
submodules: recursive
6565
- name: Build
6666
working-directory: ./build
6767
run: |
68-
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ../
68+
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_PCRE2=True ../
6969
make all
7070
- name: Test
7171
working-directory: ./build
@@ -97,13 +97,13 @@ jobs:
9797
brew install swig
9898
brew install libxmlsec1
9999
brew install openssl
100-
brew install pcre
100+
brew install pcre2
101101
102102
# Runs a set of commands using the runners shell
103103
- name: Build
104104
run: |
105105
cd $GITHUB_WORKSPACE/build
106-
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_PROBES=false ../
106+
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_PCRE2=True -DENABLE_PROBES=False ../
107107
make all
108108
109109
- name: Test

CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ find_package(Doxygen)
106106
find_package(GConf)
107107
find_package(Ldap)
108108
find_package(OpenDbx)
109-
find_package(PCRE REQUIRED)
109+
if(WITH_PCRE2)
110+
find_package(PCRE2 REQUIRED)
111+
else()
112+
find_package(PCRE REQUIRED)
113+
endif()
110114
find_package(PerlLibs)
111115
find_package(Popt)
112116
find_package(Systemd)
@@ -193,6 +197,13 @@ else()
193197
set(YAML_FILTER_FOUND FALSE)
194198
endif()
195199

200+
if(PCRE2_FOUND)
201+
set(HAVE_PCRE2 1)
202+
message("-- Using PCRE2")
203+
elseif(PCRE_FOUND)
204+
message("-- Using PCRE")
205+
endif()
206+
196207
check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
197208
check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN)
198209
check_function_exists(memalign HAVE_MEMALIGN)
@@ -330,6 +341,8 @@ cmake_dependent_option(ENABLE_OSCAP_UTIL_CHROOT "enables the oscap-chroot utilit
330341
option(ENABLE_OSCAP_UTIL_AUTOTAILOR "enables the autotailor utility that is able to perform command-line tailoring" TRUE)
331342
option(ENABLE_OSCAP_REMEDIATE_SERVICE "enables the oscap-remediate service" FALSE)
332343

344+
option(WITH_PCRE2 "use PCRE2 library" FALSE)
345+
333346
# ---------- TEST-SUITE SWITCHES
334347

335348
# Tests will be turned off on Windows, because the test suite uses bash
@@ -517,6 +530,7 @@ endif()
517530

518531
if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
519532
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -W -Wall -Wnonnull -Wshadow -Wformat -Wundef -Wno-unused-parameter -Wmissing-prototypes -Wno-unknown-pragmas -Wno-int-conversion -Werror=implicit-function-declaration -D_GNU_SOURCE -std=c99")
533+
add_link_options(-Wl,-z,now)
520534
endif()
521535
if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
522536
add_link_options(-lkvm -lm -lprocstat)
@@ -563,6 +577,7 @@ include_directories(
563577
${XMLSEC_INCLUDE_DIRS}
564578
${OPENSSL_INCLUDE_DIR}
565579
${PCRE_INCLUDE_DIRS}
580+
${PCRE2_INCLUDE_DIRS}
566581
)
567582

568583
# Honor visibility properties for all target types

cmake/FindPCRE2.cmake

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# - Find pcre
2+
# Find the native PCRE2 headers and libraries.
3+
#
4+
# PCRE2_INCLUDE_DIRS - where to find pcre2.h, etc.
5+
# PCRE2_LIBRARIES - List of libraries when using pcre.
6+
# PCRE2_FOUND - True if pcre found.
7+
8+
# Look for the header file.
9+
FIND_PATH(PCRE2_INCLUDE_DIR pcre2.h)
10+
11+
# Look for the library.
12+
FIND_LIBRARY(PCRE2_LIBRARY NAMES libpcre2.a pcre2-8)
13+
14+
# Handle the QUIETLY and REQUIRED arguments and set PCRE2_FOUND to TRUE if all listed variables are TRUE.
15+
INCLUDE(FindPackageHandleStandardArgs)
16+
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY PCRE2_INCLUDE_DIR)
17+
18+
# Copy the results to the output variables.
19+
IF(PCRE2_FOUND)
20+
SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY})
21+
SET(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR})
22+
ELSE(PCRE2_FOUND)
23+
SET(PCRE_LIBRARIES)
24+
SET(PCRE_INCLUDE_DIRS)
25+
ENDIF(PCRE2_FOUND)
26+
27+
MARK_AS_ADVANCED(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES)

config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#define OSCAP_DEFAULT_CPE_PATH "@OSCAP_DEFAULT_CPE_PATH@"
3030
#define OSCAP_TEMP_DIR "@OSCAP_TEMP_DIR@"
3131

32+
#cmakedefine HAVE_PCRE2
33+
3234
#cmakedefine HAVE_ATOMIC_BUILTINS
3335

3436
#cmakedefine HAVE_ACL_EXTENDED_FILE

docs/developer/developer.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-d
8989
libxmlsec1-dev libxmlsec1-openssl
9090
----
9191

92+
Since version 1.3.9 OpenSCAP can use either PCRE or PCRE2 library to handle regular
93+
expressions. The default behaviour for 1.3.x line of versions is to try and link
94+
with PCRE. In order to switxh the build system to PCRE2 one must configure
95+
CMake with '-DWITH_PCRE2=True' parameter. Dependencies: Debian/Ubuntu — pcre2-dev,
96+
Fedora/RHEL — pcre2-devel.
97+
9298
When you have all the build dependencies installed you can build the library.
9399
--
94100

@@ -319,7 +325,7 @@ behaviour.
319325
* *OSCAP_FULL_VALIDATION=1* - validate all exported documents (slower)
320326
* *SEXP_VALIDATE_DISABLE=1* - do not validate SEXP expressions (faster)
321327
* *OSCAP_PCRE_EXEC_RECURSION_LIMIT* - override default recursion limit
322-
for match in pcre_exec call in textfilecontent(54) probes.
328+
for match in pcre_exec/pcre2_match calls in textfilecontent(54) probes.
323329

324330

325331

docs/manual/manual.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,7 @@ not considered local by the scanner:
16131613
* `OSCAP_EVALUATION_TARGET` - Change value of target facts `urn:xccdf:fact:identifier` and `urn:xccdf:fact:asset:identifier:ein` in XCCDF results. Used during offline scanning to pass the name of the target system.
16141614
* `OSCAP_FULL_VALIDATION` - If set, XML schema validation will be performed in every step of SCAP content processing.
16151615
* `OSCAP_OVAL_COMMAND_OPTIONS` - Additional command line options for `oscap oval` module. The value of this environment variable is appended to the actual command line options of `oscap` command.
1616-
* `OSCAP_PCRE_EXEC_RECURSION_LIMIT` - Set recursion limit of regular expression matching using `pcre_exec` function.
1616+
* `OSCAP_PCRE_EXEC_RECURSION_LIMIT` - Set recursion limit of regular expression matching using `pcre_exec`/`pcre2_match` functions.
16171617
* `OSCAP_PROBE_ROOT` - Path to a directory which contains mounted filesystem to be evaluated. Used for offline scanning.
16181618
* `SEXP_VALIDATE_DISABLE` - If set, `oscap` will not validate SEXP expressions during its execution.
16191619
* `SOURCE_DATE_EPOCH` - Timestamp in seconds since epoch. This timestamp will be used instead of the current time to populate `timestamp` attributes in SCAP source data streams created by `oscap ds sds-compose` sub-module. This is used for reproducible builds of data streams.

openscap.spec

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ BuildRequires: apt-devel
1818
%endif
1919
BuildRequires: rpm-devel
2020
BuildRequires: libgcrypt-devel
21+
%if 0%{?fedora}
22+
BuildRequires: pcre2-devel
23+
%else
2124
BuildRequires: pcre-devel
25+
%endif
2226
BuildRequires: libacl-devel
2327
BuildRequires: libselinux-devel
2428
BuildRequires: libcap-devel
@@ -136,6 +140,9 @@ Tool for scanning Atomic containers.
136140
# gconf is a legacy system not used any more, and it blocks testing of oscap-anaconda-addon
137141
# as gconf is no longer part of the installation medium
138142
%cmake \
143+
%if 0%{?fedora}
144+
-DWITH_PCRE2=ON \
145+
%endif
139146
-DENABLE_PERL=OFF \
140147
-DENABLE_DOCS=ON \
141148
-DOPENSCAP_PROBE_UNIX_GCONF=OFF \

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ set_target_properties(openscap PROPERTIES
8181
C_VISIBILITY_PRESET hidden
8282
)
8383

84-
target_link_libraries(openscap ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${XMLSEC_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES} ${PCRE_LIBRARIES} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
84+
target_link_libraries(openscap ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${XMLSEC_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES} ${PCRE_LIBRARIES} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
8585
if (BZIP2_FOUND)
8686
target_link_libraries(openscap ${BZIP2_LIBRARIES})
8787
endif()

src/CPE/cpename.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737

3838
#include <string.h>
3939
#include <stdio.h>
40-
#include <pcre.h>
4140
#include <ctype.h>
4241

4342
#include "cpe_name.h"
4443
#include "common/util.h"
44+
#include "common/oscap_pcre.h"
4545
#include "oscap_helpers.h"
4646

4747
#define CPE_URI_SUPPORTED "2.3"
@@ -549,8 +549,8 @@ cpe_format_t cpe_name_get_format_of_str(const char *str)
549549
if (str == NULL)
550550
return CPE_FORMAT_UNKNOWN;
551551

552-
pcre *re;
553-
const char *error;
552+
oscap_pcre_t *re;
553+
char *error;
554554
int erroffset;
555555
int rc;
556556
int ovector[30];
@@ -559,26 +559,38 @@ cpe_format_t cpe_name_get_format_of_str(const char *str)
559559
// http://scap.nist.gov/schema/cpe/2.3/cpe-naming_2.3.xsd
560560
// [c] was replaced with [cC] here and in the schemas
561561

562-
re = pcre_compile("^[cC][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\\._\\-~%]*){0,6}$", 0, &error, &erroffset, NULL);
563-
rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30);
564-
pcre_free(re);
562+
re = oscap_pcre_compile("^[cC][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\\._\\-~%]*){0,6}$", 0, &error, &erroffset);
563+
if (re == NULL) {
564+
oscap_pcre_err_free(error);
565+
return CPE_FORMAT_UNKNOWN;
566+
}
567+
rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30);
568+
oscap_pcre_free(re);
565569

566570
if (rc >= 0)
567571
return CPE_FORMAT_URI;
568572

569573
// The regex was taken from the official XSD at
570574
// http://scap.nist.gov/schema/cpe/2.3/cpe-naming_2.3.xsd
571-
re = pcre_compile("^cpe:2\\.3:[aho\\*\\-](:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\\*\\-]))(:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){4}$", 0, &error, &erroffset, NULL);
572-
rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30);
573-
pcre_free(re);
575+
re = oscap_pcre_compile("^cpe:2\\.3:[aho\\*\\-](:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\\*\\-]))(:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){4}$", 0, &error, &erroffset);
576+
if (re == NULL) {
577+
oscap_pcre_err_free(error);
578+
return CPE_FORMAT_UNKNOWN;
579+
}
580+
rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30);
581+
oscap_pcre_free(re);
574582

575583
if (rc >= 0)
576584
return CPE_FORMAT_STRING;
577585

578586
// FIXME: This should be way more strict
579-
re = pcre_compile("^wfn:\\[.+\\]$", PCRE_CASELESS, &error, &erroffset, NULL);
580-
rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30);
581-
pcre_free(re);
587+
re = oscap_pcre_compile("^wfn:\\[.+\\]$", OSCAP_PCRE_OPTS_CASELESS, &error, &erroffset);
588+
if (re == NULL) {
589+
oscap_pcre_err_free(error);
590+
return CPE_FORMAT_UNKNOWN;
591+
}
592+
rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30);
593+
oscap_pcre_free(re);
582594

583595
if (rc >= 0)
584596
return CPE_FORMAT_WFN;

src/OVAL/oval_component.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
#include "common/debug_priv.h"
5656
#include "common/_error.h"
5757
#include "common/oscap_string.h"
58+
#include "common/oscap_pcre.h"
5859
#include "oval_glob_to_regex.h"
59-
#include <pcre.h>
6060

6161
#if !defined(OVAL_PROBES_ENABLED)
6262
const char *oval_subtype_to_str(oval_subtype_t subtype);
@@ -1980,12 +1980,16 @@ static long unsigned int _parse_fmt_sse(char *dt)
19801980
static bool _match(const char *pattern, const char *string)
19811981
{
19821982
bool match = false;
1983-
pcre *re;
1984-
const char *error;
1983+
oscap_pcre_t *re;
1984+
char *error;
19851985
int erroffset = -1, ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]);
1986-
re = pcre_compile(pattern, PCRE_UTF8, &error, &erroffset, NULL);
1987-
match = (pcre_exec(re, NULL, string, strlen(string), 0, 0, ovector, ovector_len) >= 0);
1988-
pcre_free(re);
1986+
re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &error, &erroffset);
1987+
if (re == NULL) {
1988+
oscap_pcre_err_free(error);
1989+
return false;
1990+
}
1991+
match = (oscap_pcre_exec(re, string, strlen(string), 0, 0, ovector, ovector_len) >= 0);
1992+
oscap_pcre_free(re);
19891993
return match;
19901994
}
19911995

@@ -2208,13 +2212,14 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova
22082212
int rc;
22092213
char *pattern;
22102214
int erroffset = -1;
2211-
pcre *re = NULL;
2212-
const char *error;
2215+
oscap_pcre_t *re = NULL;
2216+
char *error;
22132217

22142218
pattern = oval_component_get_regex_pattern(component);
2215-
re = pcre_compile(pattern, PCRE_UTF8, &error, &erroffset, NULL);
2219+
re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &error, &erroffset);
22162220
if (re == NULL) {
2217-
dE("pcre_compile() failed: \"%s\".", error);
2221+
dE("oscap_pcre_compile() failed: \"%s\".", error);
2222+
oscap_pcre_err_free(error);
22182223
return SYSCHAR_FLAG_ERROR;
22192224
}
22202225

@@ -2233,9 +2238,9 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova
22332238
for (i = 0; i < ovector_len; ++i)
22342239
ovector[i] = -1;
22352240

2236-
rc = pcre_exec(re, NULL, text, strlen(text), 0, 0, ovector, ovector_len);
2241+
rc = oscap_pcre_exec(re, text, strlen(text), 0, 0, ovector, ovector_len);
22372242
if (rc < -1) {
2238-
dE("pcre_exec() failed: %d.", rc);
2243+
dE("oscap_pcre_exec() failed: %d.", rc);
22392244
flag = SYSCHAR_FLAG_ERROR;
22402245
break;
22412246
}
@@ -2263,7 +2268,7 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova
22632268
oval_collection_free_items(subcoll, (oscap_destruct_func) oval_value_free);
22642269
}
22652270
oval_component_iterator_free(subcomps);
2266-
pcre_free(re);
2271+
oscap_pcre_free(re);
22672272
return flag;
22682273
}
22692274

0 commit comments

Comments
 (0)