Coverage Report

Created: 2025-11-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/pcre/pcre2lib/pcre2_context.c
Line
Count
Source
1
/*************************************************
2
*      Perl-Compatible Regular Expressions       *
3
*************************************************/
4
5
/* PCRE is a library of functions to support regular expressions whose syntax
6
and semantics are as close as possible to those of the Perl 5 language.
7
8
                       Written by Philip Hazel
9
     Original API code Copyright (c) 1997-2012 University of Cambridge
10
          New API code Copyright (c) 2016-2024 University of Cambridge
11
12
-----------------------------------------------------------------------------
13
Redistribution and use in source and binary forms, with or without
14
modification, are permitted provided that the following conditions are met:
15
16
    * Redistributions of source code must retain the above copyright notice,
17
      this list of conditions and the following disclaimer.
18
19
    * Redistributions in binary form must reproduce the above copyright
20
      notice, this list of conditions and the following disclaimer in the
21
      documentation and/or other materials provided with the distribution.
22
23
    * Neither the name of the University of Cambridge nor the names of its
24
      contributors may be used to endorse or promote products derived from
25
      this software without specific prior written permission.
26
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
POSSIBILITY OF SUCH DAMAGE.
38
-----------------------------------------------------------------------------
39
*/
40
41
42
#ifdef HAVE_CONFIG_H
43
#include "config.h"
44
#endif
45
46
#include "pcre2_internal.h"
47
48
49
50
/*************************************************
51
*          Default malloc/free functions         *
52
*************************************************/
53
54
/* Ignore the "user data" argument in each case. */
55
56
static void *default_malloc(size_t size, void *data)
57
0
{
58
0
(void)data;
59
0
return malloc(size);
60
0
}
61
62
63
static void default_free(void *block, void *data)
64
0
{
65
0
(void)data;
66
0
free(block);
67
0
}
68
69
70
71
/*************************************************
72
*        Get a block and save memory control     *
73
*************************************************/
74
75
/* This internal function is called to get a block of memory in which the
76
memory control data is to be stored at the start for future use.
77
78
Arguments:
79
  size        amount of memory required
80
  memctl      pointer to a memctl block or NULL
81
82
Returns:      pointer to memory or NULL on failure
83
*/
84
85
extern void *
86
PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)
87
203
{
88
203
pcre2_memctl *newmemctl;
89
203
void *yield = (memctl == NULL)? malloc(size) :
90
203
  memctl->malloc(size, memctl->memory_data);
91
203
if (yield == NULL) return NULL;
92
203
newmemctl = (pcre2_memctl *)yield;
93
203
if (memctl == NULL)
94
0
  {
95
0
  newmemctl->malloc = default_malloc;
96
0
  newmemctl->free = default_free;
97
0
  newmemctl->memory_data = NULL;
98
0
  }
99
203
else *newmemctl = *memctl;
100
203
return yield;
101
203
}
102
103
104
105
/*************************************************
106
*          Create and initialize contexts        *
107
*************************************************/
108
109
/* Initializing for compile and match contexts is done in separate, private
110
functions so that these can be called from functions such as pcre2_compile()
111
when an external context is not supplied. The initializing functions have an
112
option to set up default memory management. */
113
114
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
115
pcre2_general_context_create(void *(*private_malloc)(size_t, void *),
116
  void (*private_free)(void *, void *), void *memory_data)
117
247k
{
118
247k
pcre2_general_context *gcontext;
119
247k
if (private_malloc == NULL) private_malloc = default_malloc;
120
247k
if (private_free == NULL) private_free = default_free;
121
247k
gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
122
247k
if (gcontext == NULL) return NULL;
123
247k
gcontext->memctl.malloc = private_malloc;
124
247k
gcontext->memctl.free = private_free;
125
247k
gcontext->memctl.memory_data = memory_data;
126
247k
return gcontext;
127
247k
}
128
129
130
/* A default compile context is set up to save having to initialize at run time
131
when no context is supplied to the compile function. */
132
133
const pcre2_compile_context PRIV(default_compile_context) = {
134
  { default_malloc, default_free, NULL },    /* Default memory handling */
135
  NULL,                                      /* Stack guard */
136
  NULL,                                      /* Stack guard data */
137
  PRIV(default_tables),                      /* Character tables */
138
  PCRE2_UNSET,                               /* Max pattern length */
139
  PCRE2_UNSET,                               /* Max pattern compiled length */
140
  BSR_DEFAULT,                               /* Backslash R default */
141
  NEWLINE_DEFAULT,                           /* Newline convention */
142
  PARENS_NEST_LIMIT,                         /* As it says */
143
  0,                                         /* Extra options */
144
  MAX_VARLOOKBEHIND                          /* As it says */
145
  };
146
147
/* The create function copies the default into the new memory, but must
148
override the default memory handling functions if a gcontext was provided. */
149
150
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
151
pcre2_compile_context_create(pcre2_general_context *gcontext)
152
16
{
153
16
pcre2_compile_context *ccontext = PRIV(memctl_malloc)(
154
16
  sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);
155
16
if (ccontext == NULL) return NULL;
156
16
*ccontext = PRIV(default_compile_context);
157
16
if (gcontext != NULL)
158
16
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
159
16
return ccontext;
160
16
}
161
162
163
/* A default match context is set up to save having to initialize at run time
164
when no context is supplied to a match function. */
165
166
const pcre2_match_context PRIV(default_match_context) = {
167
  { default_malloc, default_free, NULL },
168
#ifdef SUPPORT_JIT
169
  NULL,          /* JIT callback */
170
  NULL,          /* JIT callback data */
171
#endif
172
  NULL,          /* Callout function */
173
  NULL,          /* Callout data */
174
  NULL,          /* Substitute callout function */
175
  NULL,          /* Substitute callout data */
176
  PCRE2_UNSET,   /* Offset limit */
177
  HEAP_LIMIT,
178
  MATCH_LIMIT,
179
  MATCH_LIMIT_DEPTH };
180
181
/* The create function copies the default into the new memory, but must
182
override the default memory handling functions if a gcontext was provided. */
183
184
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
185
pcre2_match_context_create(pcre2_general_context *gcontext)
186
16
{
187
16
pcre2_match_context *mcontext = PRIV(memctl_malloc)(
188
16
  sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);
189
16
if (mcontext == NULL) return NULL;
190
16
*mcontext = PRIV(default_match_context);
191
16
if (gcontext != NULL)
192
16
  *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);
193
16
return mcontext;
194
16
}
195
196
197
/* A default convert context is set up to save having to initialize at run time
198
when no context is supplied to the convert function. */
199
200
const pcre2_convert_context PRIV(default_convert_context) = {
201
  { default_malloc, default_free, NULL },    /* Default memory handling */
202
#ifdef _WIN32
203
  CHAR_BACKSLASH,                            /* Default path separator */
204
  CHAR_GRAVE_ACCENT                          /* Default escape character */
205
#else  /* Not Windows */
206
  CHAR_SLASH,                                /* Default path separator */
207
  CHAR_BACKSLASH                             /* Default escape character */
208
#endif
209
  };
210
211
/* The create function copies the default into the new memory, but must
212
override the default memory handling functions if a gcontext was provided. */
213
214
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
215
pcre2_convert_context_create(pcre2_general_context *gcontext)
216
0
{
217
0
pcre2_convert_context *ccontext = PRIV(memctl_malloc)(
218
0
  sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);
219
0
if (ccontext == NULL) return NULL;
220
0
*ccontext = PRIV(default_convert_context);
221
0
if (gcontext != NULL)
222
0
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
223
0
return ccontext;
224
0
}
225
226
227
/*************************************************
228
*              Context copy functions            *
229
*************************************************/
230
231
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
232
pcre2_general_context_copy(pcre2_general_context *gcontext)
233
0
{
234
0
pcre2_general_context *newcontext =
235
0
  gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
236
0
  gcontext->memctl.memory_data);
237
0
if (newcontext == NULL) return NULL;
238
0
memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context));
239
0
return newcontext;
240
0
}
241
242
243
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
244
pcre2_compile_context_copy(pcre2_compile_context *ccontext)
245
0
{
246
0
pcre2_compile_context *newcontext =
247
0
  ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
248
0
  ccontext->memctl.memory_data);
249
0
if (newcontext == NULL) return NULL;
250
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context));
251
0
return newcontext;
252
0
}
253
254
255
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
256
pcre2_match_context_copy(pcre2_match_context *mcontext)
257
0
{
258
0
pcre2_match_context *newcontext =
259
0
  mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
260
0
  mcontext->memctl.memory_data);
261
0
if (newcontext == NULL) return NULL;
262
0
memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context));
263
0
return newcontext;
264
0
}
265
266
267
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
268
pcre2_convert_context_copy(pcre2_convert_context *ccontext)
269
0
{
270
0
pcre2_convert_context *newcontext =
271
0
  ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
272
0
  ccontext->memctl.memory_data);
273
0
if (newcontext == NULL) return NULL;
274
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context));
275
0
return newcontext;
276
0
}
277
278
279
/*************************************************
280
*              Context free functions            *
281
*************************************************/
282
283
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
284
pcre2_general_context_free(pcre2_general_context *gcontext)
285
247k
{
286
247k
if (gcontext != NULL)
287
247k
  gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);
288
247k
}
289
290
291
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
292
pcre2_compile_context_free(pcre2_compile_context *ccontext)
293
0
{
294
0
if (ccontext != NULL)
295
0
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
296
0
}
297
298
299
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
300
pcre2_match_context_free(pcre2_match_context *mcontext)
301
0
{
302
0
if (mcontext != NULL)
303
0
  mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);
304
0
}
305
306
307
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
308
pcre2_convert_context_free(pcre2_convert_context *ccontext)
309
0
{
310
0
if (ccontext != NULL)
311
0
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
312
0
}
313
314
315
/*************************************************
316
*             Set values in contexts             *
317
*************************************************/
318
319
/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
320
data is given. Only some of the functions are able to test the validity of the
321
data. */
322
323
324
/* ------------ Compile context ------------ */
325
326
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
327
pcre2_set_character_tables(pcre2_compile_context *ccontext,
328
  const uint8_t *tables)
329
1.52k
{
330
1.52k
ccontext->tables = tables;
331
1.52k
return 0;
332
1.52k
}
333
334
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
335
pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)
336
0
{
337
0
switch(value)
338
0
  {
339
0
  case PCRE2_BSR_ANYCRLF:
340
0
  case PCRE2_BSR_UNICODE:
341
0
  ccontext->bsr_convention = value;
342
0
  return 0;
343
344
0
  default:
345
0
  return PCRE2_ERROR_BADDATA;
346
0
  }
347
0
}
348
349
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
350
pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
351
0
{
352
0
ccontext->max_pattern_length = length;
353
0
return 0;
354
0
}
355
356
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
357
pcre2_set_max_pattern_compiled_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
358
0
{
359
0
ccontext->max_pattern_compiled_length = length;
360
0
return 0;
361
0
}
362
363
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
364
pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
365
0
{
366
0
switch(newline)
367
0
  {
368
0
  case PCRE2_NEWLINE_CR:
369
0
  case PCRE2_NEWLINE_LF:
370
0
  case PCRE2_NEWLINE_CRLF:
371
0
  case PCRE2_NEWLINE_ANY:
372
0
  case PCRE2_NEWLINE_ANYCRLF:
373
0
  case PCRE2_NEWLINE_NUL:
374
0
  ccontext->newline_convention = newline;
375
0
  return 0;
376
377
0
  default:
378
0
  return PCRE2_ERROR_BADDATA;
379
0
  }
380
0
}
381
382
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
383
pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit)
384
0
{
385
0
ccontext->max_varlookbehind = limit;
386
0
return 0;
387
0
}
388
389
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
390
pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
391
0
{
392
0
ccontext->parens_nest_limit = limit;
393
0
return 0;
394
0
}
395
396
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
397
pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)
398
1.52k
{
399
1.52k
ccontext->extra_options = options;
400
1.52k
return 0;
401
1.52k
}
402
403
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
404
pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
405
  int (*guard)(uint32_t, void *), void *user_data)
406
0
{
407
0
ccontext->stack_guard = guard;
408
0
ccontext->stack_guard_data = user_data;
409
0
return 0;
410
0
}
411
412
413
/* ------------ Match context ------------ */
414
415
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
416
pcre2_set_callout(pcre2_match_context *mcontext,
417
  int (*callout)(pcre2_callout_block *, void *), void *callout_data)
418
0
{
419
0
mcontext->callout = callout;
420
0
mcontext->callout_data = callout_data;
421
0
return 0;
422
0
}
423
424
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
425
pcre2_set_substitute_callout(pcre2_match_context *mcontext,
426
  int (*substitute_callout)(pcre2_substitute_callout_block *, void *),
427
    void *substitute_callout_data)
428
0
{
429
0
mcontext->substitute_callout = substitute_callout;
430
0
mcontext->substitute_callout_data = substitute_callout_data;
431
0
return 0;
432
0
}
433
434
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
435
pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)
436
0
{
437
0
mcontext->heap_limit = limit;
438
0
return 0;
439
0
}
440
441
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
442
pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
443
16
{
444
16
mcontext->match_limit = limit;
445
16
return 0;
446
16
}
447
448
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
449
pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
450
16
{
451
16
mcontext->depth_limit = limit;
452
16
return 0;
453
16
}
454
455
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
456
pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
457
0
{
458
0
mcontext->offset_limit = limit;
459
0
return 0;
460
0
}
461
462
/* These functions became obsolete at release 10.30. The first is kept as a
463
synonym for backwards compatibility. The second now does nothing. Exclude both
464
from coverage reports. */
465
466
/* LCOV_EXCL_START */
467
468
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
469
pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
470
0
{
471
0
return pcre2_set_depth_limit(mcontext, limit);
472
0
}
473
474
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
475
pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
476
  void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
477
  void *mydata)
478
0
{
479
0
(void)mcontext;
480
0
(void)mymalloc;
481
0
(void)myfree;
482
0
(void)mydata;
483
0
return 0;
484
0
}
485
486
/* LCOV_EXCL_STOP */
487
488
489
/* ------------ Convert context ------------ */
490
491
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
492
pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)
493
0
{
494
0
if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&
495
0
    separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;
496
0
ccontext->glob_separator = separator;
497
0
return 0;
498
0
}
499
500
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
501
pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
502
0
{
503
0
if (escape > 255 || (escape != 0 && !ispunct(escape)))
504
0
  return PCRE2_ERROR_BADDATA;
505
0
ccontext->glob_escape = escape;
506
0
return 0;
507
0
}
508
509
/* End of pcre2_context.c */
510