The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
regex.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 #ifdef HAVE_REGEX
18 /** Wrappers around various regular expression libraries
19  *
20  * @file src/lib/util/regex.h
21  *
22  * @copyright 2014 The FreeRADIUS server project
23  */
24 RCSIDH(regex_h, "$Id: d1674f45ae7a13eb0e2d970156d9073de36b73f5 $")
25 
26 # ifdef __cplusplus
27 extern "C" {
28 # endif
29 
30 #include <freeradius-devel/build.h>
31 #include <freeradius-devel/missing.h>
32 #include <freeradius-devel/util/sbuff.h>
33 #include <freeradius-devel/util/talloc.h>
34 #include <freeradius-devel/util/value.h>
35 
36 #include <stdbool.h>
37 #include <stdint.h>
38 #include <unistd.h>
39 
40 /*
41  *######################################
42  *# STRUCTURES FOR LIBPCRE2 #
43  *######################################
44  */
45 # ifdef HAVE_REGEX_PCRE2
46 # define PCRE2_CODE_UNIT_WIDTH 8
47 # include <pcre2.h>
48 /*
49  * libpcre defines its matches as an array of ints which is a
50  * multiple of three.
51  */
52 
53 /** libpcre2 has its own matchdata struct, we wrap it so we can use talloc destructors
54  *
55  */
56 typedef struct {
57  pcre2_match_data *match_data; //!< Match data containing the subject
58  ///< and various match offsets.
59  size_t used; //!< Number of slots filled with match data.
60 #ifndef NDEBUG
61  char const *subject; //!< Here for debugging purposes if we explicitly duped the string.
62 #endif
63 } fr_regmatch_t;
64 
65 typedef struct {
66  pcre2_code *compiled; //!< Compiled regular expression.
67  uint32_t subcaptures; //!< Number of subcaptures contained within the expression.
68 
69  bool precompiled; //!< Whether this regex was precompiled,
70  ///< or compiled for one off evaluation.
71  bool jitd; //!< Whether JIT data is available.
72 } regex_t;
73 /*
74  *######################################
75  *# STRUCTURES FOR LIBPCRE #
76  *######################################
77  */
78 # elif defined(HAVE_REGEX_PCRE)
79 # include <pcre.h>
80 /*
81  * Versions older then 8.20 didn't have the JIT functionality
82  * so, gracefully degrade.
83  */
84 # ifndef PCRE_STUDY_JIT_COMPILE
85 # define PCRE_STUDY_JIT_COMPILE 0
86 # endif
87 /*
88  * libpcre defines its matches as an array of ints which is a
89  * multiple of three.
90  */
91 typedef struct {
92  int a;
93  int b;
94  int c;
95 } regmatch_t;
96 
97 /** Emulates the functionality of the pcre2_match_data struct
98  *
99  */
100 typedef struct {
101  regmatch_t *match_data; //!< Slots for matches.
102  size_t allocd; //!< Number of slots allocated for match data.
103  size_t used; //!< Number of slots filled with match data.
104  char const *subject; //!< A local copy of the subject.
105 } fr_regmatch_t;
106 
107 /** Bundles compiled regular expression structures together
108  *
109  */
110 typedef struct {
111  pcre *compiled; //!< Compiled regular expression.
112  pcre_extra *extra; //!< Result of studying a regular expression.
113  uint32_t subcaptures; //!< Number of subcaptures contained within the expression.
114 
115  bool precompiled; //!< Whether this regex was precompiled, or compiled for one off evaluation.
116  bool jitd; //!< Whether JIT data is available.
117 } regex_t;
118 /*
119  *######################################
120  *# STRUCTURES FOR POSIX-REGEX #
121  *######################################
122  */
123 # else
124 # include <regex.h>
125 /*
126  * Allow REG_EXTENDED and REG_NOSUB to be or'd with flags
127  * if they're not defined.
128  */
129 # ifndef REG_EXTENDED
130 # define REG_EXTENDED (0)
131 # endif
132 
133 # ifndef REG_NOSUB
134 # define REG_NOSUB (0)
135 # endif
136 
137 /** Emulates the functionality of the pcre2_match_data struct
138  *
139  */
140 typedef struct {
141  regmatch_t *match_data; //!< Slots for matches.
142  size_t allocd; //!< Number of slots allocated for match data.
143  size_t used; //!< Number of slots filled with match data.
144  char const *subject; //!< A local copy of the subject.
145 } fr_regmatch_t;
146 
147 # endif
148 
149 /*
150  *########################################
151  *# UNIVERSAL FUNCTIONS AND STRUCTURES #
152  *########################################
153  */
154 
155 /** The set of all flags implemented by the different regex libraries
156  *
157  * A specific library may not implement all these flags. If an unsupported flag is high
158  * then the library will produce an error.
159  */
160 typedef struct {
161  uint8_t global:1; //!< g - Perform global matching or substitution.
162  uint8_t ignore_case:1; //!< i - Perform case insensitive matching.
163  uint8_t multiline:1; //!< m - Multiline search.
164  uint8_t dot_all:1; //!< s - Singleline - '.' matches everything, including newlines.
165  uint8_t unicode:1; //!< u - Use unicode properties for character with code points
166  ///< greater than 127.
167  uint8_t extended:1; //!< x - Permit whitespace and comments.
168 } fr_regex_flags_t;
169 
170 #define REGEX_FLAG_BUFF_SIZE 7
171 
172 /** Unique safefor value to prevent escaping for regexes
173  */
174 #define FR_REGEX_SAFE_FOR ((uintptr_t)regex_exec)
175 
176 ssize_t regex_flags_parse(int *err, fr_regex_flags_t *out, fr_sbuff_t *in,
177  fr_sbuff_term_t const *terminals, bool err_on_dup);
178 
179 ssize_t regex_flags_print(fr_sbuff_t *sbuff, fr_regex_flags_t const *flags);
180 
181  ssize_t regex_compile(TALLOC_CTX *ctx, regex_t **out, char const *pattern, size_t len,
182  fr_regex_flags_t const *flags, bool subcaptures, bool runtime);
183 int regex_exec(regex_t *preg, char const *subject, size_t len, fr_regmatch_t *regmatch) CC_HINT(nonnull(1,2));
184 #ifdef HAVE_REGEX_PCRE2
185 int regex_substitute(TALLOC_CTX *ctx, char **out, size_t max_out, regex_t *preg, fr_regex_flags_t const *flags,
186  char const *subject, size_t subject_len,
187  char const *replacement, size_t replacement_len,
188  fr_regmatch_t *regmatch);
189 #endif
190 uint32_t regex_subcapture_count(regex_t const *preg);
191 fr_regmatch_t *regex_match_data_alloc(TALLOC_CTX *ctx, uint32_t count);
192 
193 int fr_regex_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b) CC_HINT(nonnull);
194 
195 # ifdef __cplusplus
196 }
197 # endif
198 #endif
#define RCSIDH(h, id)
Definition: build.h:482
static fr_slen_t err
Definition: dict.h:821
static fr_slen_t in
Definition: dict.h:821
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
static size_t used
Set of terminal elements.
Definition: merged_model.c:161
return count
Definition: module.c:163
enum fr_token fr_token_t
int fr_regex_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two boxes using an operator.
Definition: regex.c:1360
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997