Coverage Report

Created: 2025-06-13 06:43

/src/php-src/ext/pcre/pcre2lib/pcre2_context.c
Line
Count
Source (jump to first uncovered line)
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
200
{
88
200
pcre2_memctl *newmemctl;
89
200
void *yield = (memctl == NULL)? malloc(size) :
90
200
  memctl->malloc(size, memctl->memory_data);
91
200
if (yield == NULL) return NULL;
92
200
newmemctl = (pcre2_memctl *)yield;
93
200
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
200
else *newmemctl = *memctl;
100
200
return yield;
101
200
}
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
300k
{
118
300k
pcre2_general_context *gcontext;
119
300k
if (private_malloc == NULL) private_malloc = default_malloc;
120
300k
if (private_free == NULL) private_free = default_free;
121
300k
gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
122
300k
if (gcontext == NULL) return NULL;
123
300k
gcontext->memctl.malloc = private_malloc;
124
300k
gcontext->memctl.free = private_free;
125
300k
gcontext->memctl.memory_data = memory_data;
126
300k
return gcontext;
127
300k
}
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
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
  PCRE2_OPTIMIZATION_ALL                     /* All optimizations enabled */
146
  };
147
148
/* The create function copies the default into the new memory, but must
149
override the default memory handling functions if a gcontext was provided. */
150
151
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
152
pcre2_compile_context_create(pcre2_general_context *gcontext)
153
16
{
154
16
pcre2_compile_context *ccontext = PRIV(memctl_malloc)(
155
16
  sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);
156
16
if (ccontext == NULL) return NULL;
157
16
*ccontext = PRIV(default_compile_context);
158
16
if (gcontext != NULL)
159
16
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
160
16
return ccontext;
161
16
}
162
163
164
/* A default match context is set up to save having to initialize at run time
165
when no context is supplied to a match function. */
166
167
pcre2_match_context PRIV(default_match_context) = {
168
  { default_malloc, default_free, NULL },
169
#ifdef SUPPORT_JIT
170
  NULL,          /* JIT callback */
171
  NULL,          /* JIT callback data */
172
#endif
173
  NULL,          /* Callout function */
174
  NULL,          /* Callout data */
175
  NULL,          /* Substitute callout function */
176
  NULL,          /* Substitute callout data */
177
  NULL,          /* Substitute case callout function */
178
  NULL,          /* Substitute case callout data */
179
  PCRE2_UNSET,   /* Offset limit */
180
  HEAP_LIMIT,
181
  MATCH_LIMIT,
182
  MATCH_LIMIT_DEPTH };
183
184
/* The create function copies the default into the new memory, but must
185
override the default memory handling functions if a gcontext was provided. */
186
187
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
188
pcre2_match_context_create(pcre2_general_context *gcontext)
189
16
{
190
16
pcre2_match_context *mcontext = PRIV(memctl_malloc)(
191
16
  sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);
192
16
if (mcontext == NULL) return NULL;
193
16
*mcontext = PRIV(default_match_context);
194
16
if (gcontext != NULL)
195
16
  *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);
196
16
return mcontext;
197
16
}
198
199
200
/* A default convert context is set up to save having to initialize at run time
201
when no context is supplied to the convert function. */
202
203
pcre2_convert_context PRIV(default_convert_context) = {
204
  { default_malloc, default_free, NULL },    /* Default memory handling */
205
#ifdef _WIN32
206
  CHAR_BACKSLASH,                            /* Default path separator */
207
  CHAR_GRAVE_ACCENT                          /* Default escape character */
208
#else  /* Not Windows */
209
  CHAR_SLASH,                                /* Default path separator */
210
  CHAR_BACKSLASH                             /* Default escape character */
211
#endif
212
  };
213
214
/* The create function copies the default into the new memory, but must
215
override the default memory handling functions if a gcontext was provided. */
216
217
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
218
pcre2_convert_context_create(pcre2_general_context *gcontext)
219
0
{
220
0
pcre2_convert_context *ccontext = PRIV(memctl_malloc)(
221
0
  sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);
222
0
if (ccontext == NULL) return NULL;
223
0
*ccontext = PRIV(default_convert_context);
224
0
if (gcontext != NULL)
225
0
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
226
0
return ccontext;
227
0
}
228
229
230
/*************************************************
231
*              Context copy functions            *
232
*************************************************/
233
234
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
235
pcre2_general_context_copy(pcre2_general_context *gcontext)
236
0
{
237
0
pcre2_general_context *newcontext =
238
0
  gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
239
0
  gcontext->memctl.memory_data);
240
0
if (newcontext == NULL) return NULL;
241
0
memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context));
242
0
return newcontext;
243
0
}
244
245
246
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
247
pcre2_compile_context_copy(pcre2_compile_context *ccontext)
248
0
{
249
0
pcre2_compile_context *newcontext =
250
0
  ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
251
0
  ccontext->memctl.memory_data);
252
0
if (newcontext == NULL) return NULL;
253
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context));
254
0
return newcontext;
255
0
}
256
257
258
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
259
pcre2_match_context_copy(pcre2_match_context *mcontext)
260
0
{
261
0
pcre2_match_context *newcontext =
262
0
  mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
263
0
  mcontext->memctl.memory_data);
264
0
if (newcontext == NULL) return NULL;
265
0
memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context));
266
0
return newcontext;
267
0
}
268
269
270
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
271
pcre2_convert_context_copy(pcre2_convert_context *ccontext)
272
0
{
273
0
pcre2_convert_context *newcontext =
274
0
  ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
275
0
  ccontext->memctl.memory_data);
276
0
if (newcontext == NULL) return NULL;
277
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context));
278
0
return newcontext;
279
0
}
280
281
282
/*************************************************
283
*              Context free functions            *
284
*************************************************/
285
286
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
287
pcre2_general_context_free(pcre2_general_context *gcontext)
288
300k
{
289
300k
if (gcontext != NULL)
290
300k
  gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);
291
300k
}
292
293
294
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
295
pcre2_compile_context_free(pcre2_compile_context *ccontext)
296
0
{
297
0
if (ccontext != NULL)
298
0
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
299
0
}
300
301
302
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
303
pcre2_match_context_free(pcre2_match_context *mcontext)
304
0
{
305
0
if (mcontext != NULL)
306
0
  mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);
307
0
}
308
309
310
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
311
pcre2_convert_context_free(pcre2_convert_context *ccontext)
312
0
{
313
0
if (ccontext != NULL)
314
0
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
315
0
}
316
317
318
/*************************************************
319
*             Set values in contexts             *
320
*************************************************/
321
322
/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
323
data is given. Only some of the functions are able to test the validity of the
324
data. */
325
326
327
/* ------------ Compile context ------------ */
328
329
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
330
pcre2_set_character_tables(pcre2_compile_context *ccontext,
331
  const uint8_t *tables)
332
2.39k
{
333
2.39k
ccontext->tables = tables;
334
2.39k
return 0;
335
2.39k
}
336
337
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
338
pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)
339
0
{
340
0
switch(value)
341
0
  {
342
0
  case PCRE2_BSR_ANYCRLF:
343
0
  case PCRE2_BSR_UNICODE:
344
0
  ccontext->bsr_convention = value;
345
0
  return 0;
346
347
0
  default:
348
0
  return PCRE2_ERROR_BADDATA;
349
0
  }
350
0
}
351
352
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
353
pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
354
0
{
355
0
ccontext->max_pattern_length = length;
356
0
return 0;
357
0
}
358
359
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
360
pcre2_set_max_pattern_compiled_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
361
0
{
362
0
ccontext->max_pattern_compiled_length = length;
363
0
return 0;
364
0
}
365
366
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
367
pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
368
0
{
369
0
switch(newline)
370
0
  {
371
0
  case PCRE2_NEWLINE_CR:
372
0
  case PCRE2_NEWLINE_LF:
373
0
  case PCRE2_NEWLINE_CRLF:
374
0
  case PCRE2_NEWLINE_ANY:
375
0
  case PCRE2_NEWLINE_ANYCRLF:
376
0
  case PCRE2_NEWLINE_NUL:
377
0
  ccontext->newline_convention = newline;
378
0
  return 0;
379
380
0
  default:
381
0
  return PCRE2_ERROR_BADDATA;
382
0
  }
383
0
}
384
385
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
386
pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit)
387
0
{
388
0
ccontext->max_varlookbehind = limit;
389
0
return 0;
390
0
}
391
392
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
393
pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
394
0
{
395
0
ccontext->parens_nest_limit = limit;
396
0
return 0;
397
0
}
398
399
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
400
pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)
401
2.39k
{
402
2.39k
ccontext->extra_options = options;
403
2.39k
return 0;
404
2.39k
}
405
406
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
407
pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
408
  int (*guard)(uint32_t, void *), void *user_data)
409
0
{
410
0
ccontext->stack_guard = guard;
411
0
ccontext->stack_guard_data = user_data;
412
0
return 0;
413
0
}
414
415
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
416
pcre2_set_optimize(pcre2_compile_context *ccontext, uint32_t directive)
417
0
{
418
0
if (ccontext == NULL)
419
0
  return PCRE2_ERROR_NULL;
420
421
0
switch (directive)
422
0
  {
423
0
  case PCRE2_OPTIMIZATION_NONE:
424
0
  ccontext->optimization_flags = 0;
425
0
  break;
426
427
0
  case PCRE2_OPTIMIZATION_FULL:
428
0
  ccontext->optimization_flags = PCRE2_OPTIMIZATION_ALL;
429
0
  break;
430
431
0
  default:
432
0
  if (directive >= PCRE2_AUTO_POSSESS && directive <= PCRE2_START_OPTIMIZE_OFF)
433
0
    {
434
    /* Even directive numbers starting from 64 switch a bit on;
435
     * Odd directive numbers starting from 65 switch a bit off */
436
0
    if ((directive & 1) != 0)
437
0
      ccontext->optimization_flags &= ~(1u << ((directive >> 1) - 32));
438
0
    else
439
0
      ccontext->optimization_flags |= 1u << ((directive >> 1) - 32);
440
0
    return 0;
441
0
    }
442
0
  return PCRE2_ERROR_BADOPTION;
443
0
  }
444
445
0
return 0;
446
0
}
447
448
/* ------------ Match context ------------ */
449
450
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
451
pcre2_set_callout(pcre2_match_context *mcontext,
452
  int (*callout)(pcre2_callout_block *, void *), void *callout_data)
453
0
{
454
0
mcontext->callout = callout;
455
0
mcontext->callout_data = callout_data;
456
0
return 0;
457
0
}
458
459
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
460
pcre2_set_substitute_callout(pcre2_match_context *mcontext,
461
  int (*substitute_callout)(pcre2_substitute_callout_block *, void *),
462
  void *substitute_callout_data)
463
0
{
464
0
mcontext->substitute_callout = substitute_callout;
465
0
mcontext->substitute_callout_data = substitute_callout_data;
466
0
return 0;
467
0
}
468
469
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
470
pcre2_set_substitute_case_callout(pcre2_match_context *mcontext,
471
  PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,
472
                                        PCRE2_SIZE, int, void *),
473
  void *substitute_case_callout_data)
474
0
{
475
0
mcontext->substitute_case_callout = substitute_case_callout;
476
0
mcontext->substitute_case_callout_data = substitute_case_callout_data;
477
0
return 0;
478
0
}
479
480
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
481
pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)
482
0
{
483
0
mcontext->heap_limit = limit;
484
0
return 0;
485
0
}
486
487
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
488
pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
489
16
{
490
16
mcontext->match_limit = limit;
491
16
return 0;
492
16
}
493
494
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
495
pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
496
16
{
497
16
mcontext->depth_limit = limit;
498
16
return 0;
499
16
}
500
501
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
502
pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
503
0
{
504
0
mcontext->offset_limit = limit;
505
0
return 0;
506
0
}
507
508
/* These functions became obsolete at release 10.30. The first is kept as a
509
synonym for backwards compatibility. The second now does nothing. Exclude both
510
from coverage reports. */
511
512
/* LCOV_EXCL_START */
513
514
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
515
pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
516
0
{
517
0
return pcre2_set_depth_limit(mcontext, limit);
518
0
}
519
520
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
521
pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
522
  void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
523
  void *mydata)
524
0
{
525
0
(void)mcontext;
526
0
(void)mymalloc;
527
0
(void)myfree;
528
0
(void)mydata;
529
0
return 0;
530
0
}
531
532
/* LCOV_EXCL_STOP */
533
534
535
/* ------------ Convert context ------------ */
536
537
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
538
pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)
539
0
{
540
0
if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&
541
0
    separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;
542
0
ccontext->glob_separator = separator;
543
0
return 0;
544
0
}
545
546
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
547
pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
548
0
{
549
0
if (escape > 255 || (escape != 0 && !ispunct(escape)))
550
0
  return PCRE2_ERROR_BADDATA;
551
0
ccontext->glob_escape = escape;
552
0
return 0;
553
0
}
554
555
/* End of pcre2_context.c */
556