Coverage Report

Created: 2025-11-24 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pcre2/src/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
#include "pcre2_internal.h"
43
44
45
46
/*************************************************
47
*          Default malloc/free functions         *
48
*************************************************/
49
50
/* Ignore the "user data" argument in each case. */
51
52
static void *default_malloc(size_t size, void *data)
53
8.43M
{
54
8.43M
(void)data;
55
8.43M
return malloc(size);
56
8.43M
}
57
58
59
static void default_free(void *block, void *data)
60
8.65M
{
61
8.65M
(void)data;
62
8.65M
free(block);
63
8.65M
}
64
65
66
67
/*************************************************
68
*        Get a block and save memory control     *
69
*************************************************/
70
71
/* This internal function is called to get a block of memory in which the
72
memory control data is to be stored at the start for future use.
73
74
Arguments:
75
  size        amount of memory required
76
  memctl      pointer to a memctl block or NULL
77
78
Returns:      pointer to memory or NULL on failure
79
*/
80
81
extern void *
82
PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)
83
149k
{
84
149k
pcre2_memctl *newmemctl;
85
149k
void *yield = (memctl == NULL)? malloc(size) :
86
149k
  memctl->malloc(size, memctl->memory_data);
87
149k
if (yield == NULL) return NULL;
88
149k
newmemctl = (pcre2_memctl *)yield;
89
149k
if (memctl == NULL)
90
149k
  {
91
149k
  newmemctl->malloc = default_malloc;
92
149k
  newmemctl->free = default_free;
93
149k
  newmemctl->memory_data = NULL;
94
149k
  }
95
0
else *newmemctl = *memctl;
96
149k
return yield;
97
149k
}
98
99
100
101
/*************************************************
102
*          Create and initialize contexts        *
103
*************************************************/
104
105
/* Initializing for compile and match contexts is done in separate, private
106
functions so that these can be called from functions such as pcre2_compile()
107
when an external context is not supplied. The initializing functions have an
108
option to set up default memory management. */
109
110
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
111
pcre2_general_context_create(void *(*private_malloc)(size_t, void *),
112
  void (*private_free)(void *, void *), void *memory_data)
113
0
{
114
0
pcre2_general_context *gcontext;
115
0
if (private_malloc == NULL) private_malloc = default_malloc;
116
0
if (private_free == NULL) private_free = default_free;
117
0
gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
118
0
if (gcontext == NULL) return NULL;
119
0
gcontext->memctl.malloc = private_malloc;
120
0
gcontext->memctl.free = private_free;
121
0
gcontext->memctl.memory_data = memory_data;
122
0
return gcontext;
123
0
}
124
125
126
/* A default compile context is set up to save having to initialize at run time
127
when no context is supplied to the compile function. */
128
129
pcre2_compile_context PRIV(default_compile_context) = {
130
  { default_malloc, default_free, NULL },    /* Default memory handling */
131
  NULL,                                      /* Stack guard */
132
  NULL,                                      /* Stack guard data */
133
  PRIV(default_tables),                      /* Character tables */
134
  PCRE2_UNSET,                               /* Max pattern length */
135
  PCRE2_UNSET,                               /* Max pattern compiled length */
136
  BSR_DEFAULT,                               /* Backslash R default */
137
  NEWLINE_DEFAULT,                           /* Newline convention */
138
  PARENS_NEST_LIMIT,                         /* As it says */
139
  0,                                         /* Extra options */
140
  MAX_VARLOOKBEHIND,                         /* As it says */
141
  PCRE2_OPTIMIZATION_ALL                     /* All optimizations enabled */
142
  };
143
144
/* The create function copies the default into the new memory, but must
145
override the default memory handling functions if a gcontext was provided. */
146
147
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
148
pcre2_compile_context_create(pcre2_general_context *gcontext)
149
40.0k
{
150
40.0k
pcre2_compile_context *ccontext = PRIV(memctl_malloc)(
151
40.0k
  sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);
152
40.0k
if (ccontext == NULL) return NULL;
153
40.0k
*ccontext = PRIV(default_compile_context);
154
40.0k
if (gcontext != NULL)
155
0
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
156
40.0k
return ccontext;
157
40.0k
}
158
159
160
/* A default match context is set up to save having to initialize at run time
161
when no context is supplied to a match function. */
162
163
pcre2_match_context PRIV(default_match_context) = {
164
  { default_malloc, default_free, NULL },
165
#ifdef SUPPORT_JIT
166
  NULL,          /* JIT callback */
167
  NULL,          /* JIT callback data */
168
#endif
169
  NULL,          /* Callout function */
170
  NULL,          /* Callout data */
171
  NULL,          /* Substitute callout function */
172
  NULL,          /* Substitute callout data */
173
  NULL,          /* Substitute case callout function */
174
  NULL,          /* Substitute case callout data */
175
  PCRE2_UNSET,   /* Offset limit */
176
  HEAP_LIMIT,
177
  MATCH_LIMIT,
178
  MATCH_LIMIT_DEPTH };
179
180
/* The create function copies the default into the new memory, but must
181
override the default memory handling functions if a gcontext was provided. */
182
183
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
184
pcre2_match_context_create(pcre2_general_context *gcontext)
185
36.4k
{
186
36.4k
pcre2_match_context *mcontext = PRIV(memctl_malloc)(
187
36.4k
  sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);
188
36.4k
if (mcontext == NULL) return NULL;
189
36.4k
*mcontext = PRIV(default_match_context);
190
36.4k
if (gcontext != NULL)
191
0
  *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);
192
36.4k
return mcontext;
193
36.4k
}
194
195
196
/* A default convert context is set up to save having to initialize at run time
197
when no context is supplied to the convert function. */
198
199
pcre2_convert_context PRIV(default_convert_context) = {
200
  { default_malloc, default_free, NULL },    /* Default memory handling */
201
#ifdef _WIN32
202
  CHAR_BACKSLASH,                            /* Default path separator */
203
  CHAR_GRAVE_ACCENT                          /* Default escape character */
204
#else  /* Not Windows */
205
  CHAR_SLASH,                                /* Default path separator */
206
  CHAR_BACKSLASH                             /* Default escape character */
207
#endif
208
  };
209
210
/* The create function copies the default into the new memory, but must
211
override the default memory handling functions if a gcontext was provided. */
212
213
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
214
pcre2_convert_context_create(pcre2_general_context *gcontext)
215
0
{
216
0
pcre2_convert_context *ccontext = PRIV(memctl_malloc)(
217
0
  sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);
218
0
if (ccontext == NULL) return NULL;
219
0
*ccontext = PRIV(default_convert_context);
220
0
if (gcontext != NULL)
221
0
  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
222
0
return ccontext;
223
0
}
224
225
226
/*************************************************
227
*              Context copy functions            *
228
*************************************************/
229
230
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
231
pcre2_general_context_copy(pcre2_general_context *gcontext)
232
0
{
233
0
pcre2_general_context *newcontext =
234
0
  gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
235
0
  gcontext->memctl.memory_data);
236
0
if (newcontext == NULL) return NULL;
237
0
memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context));
238
0
return newcontext;
239
0
}
240
241
242
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
243
pcre2_compile_context_copy(pcre2_compile_context *ccontext)
244
0
{
245
0
pcre2_compile_context *newcontext =
246
0
  ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
247
0
  ccontext->memctl.memory_data);
248
0
if (newcontext == NULL) return NULL;
249
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context));
250
0
return newcontext;
251
0
}
252
253
254
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
255
pcre2_match_context_copy(pcre2_match_context *mcontext)
256
0
{
257
0
pcre2_match_context *newcontext =
258
0
  mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
259
0
  mcontext->memctl.memory_data);
260
0
if (newcontext == NULL) return NULL;
261
0
memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context));
262
0
return newcontext;
263
0
}
264
265
266
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
267
pcre2_convert_context_copy(pcre2_convert_context *ccontext)
268
0
{
269
0
pcre2_convert_context *newcontext =
270
0
  ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
271
0
  ccontext->memctl.memory_data);
272
0
if (newcontext == NULL) return NULL;
273
0
memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context));
274
0
return newcontext;
275
0
}
276
277
278
/*************************************************
279
*              Context free functions            *
280
*************************************************/
281
282
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
283
pcre2_general_context_free(pcre2_general_context *gcontext)
284
0
{
285
0
if (gcontext != NULL)
286
0
  gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);
287
0
}
288
289
290
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
291
pcre2_compile_context_free(pcre2_compile_context *ccontext)
292
40.0k
{
293
40.0k
if (ccontext != NULL)
294
40.0k
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
295
40.0k
}
296
297
298
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
299
pcre2_match_context_free(pcre2_match_context *mcontext)
300
36.4k
{
301
36.4k
if (mcontext != NULL)
302
36.4k
  mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);
303
36.4k
}
304
305
306
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
307
pcre2_convert_context_free(pcre2_convert_context *ccontext)
308
0
{
309
0
if (ccontext != NULL)
310
0
  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
311
0
}
312
313
314
/*************************************************
315
*             Set values in contexts             *
316
*************************************************/
317
318
/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
319
data is given. Only some of the functions are able to test the validity of the
320
data. */
321
322
323
/* ------------ Compile context ------------ */
324
325
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
326
pcre2_set_character_tables(pcre2_compile_context *ccontext,
327
  const uint8_t *tables)
328
0
{
329
0
ccontext->tables = tables;
330
0
return 0;
331
0
}
332
333
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
334
pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)
335
0
{
336
0
switch(value)
337
0
  {
338
0
  case PCRE2_BSR_ANYCRLF:
339
0
  case PCRE2_BSR_UNICODE:
340
0
  ccontext->bsr_convention = value;
341
0
  return 0;
342
343
0
  default:
344
0
  return PCRE2_ERROR_BADDATA;
345
0
  }
346
0
}
347
348
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
349
pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
350
0
{
351
0
ccontext->max_pattern_length = length;
352
0
return 0;
353
0
}
354
355
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
356
pcre2_set_max_pattern_compiled_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
357
40.0k
{
358
40.0k
ccontext->max_pattern_compiled_length = length;
359
40.0k
return 0;
360
40.0k
}
361
362
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
363
pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
364
0
{
365
0
switch(newline)
366
0
  {
367
0
  case PCRE2_NEWLINE_CR:
368
0
  case PCRE2_NEWLINE_LF:
369
0
  case PCRE2_NEWLINE_CRLF:
370
0
  case PCRE2_NEWLINE_ANY:
371
0
  case PCRE2_NEWLINE_ANYCRLF:
372
0
  case PCRE2_NEWLINE_NUL:
373
0
  ccontext->newline_convention = newline;
374
0
  return 0;
375
376
0
  default:
377
0
  return PCRE2_ERROR_BADDATA;
378
0
  }
379
0
}
380
381
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
382
pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit)
383
0
{
384
0
ccontext->max_varlookbehind = limit;
385
0
return 0;
386
0
}
387
388
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
389
pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
390
0
{
391
0
ccontext->parens_nest_limit = limit;
392
0
return 0;
393
0
}
394
395
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
396
pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)
397
0
{
398
0
ccontext->extra_options = options;
399
0
return 0;
400
0
}
401
402
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
403
pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
404
  int (*guard)(uint32_t, void *), void *user_data)
405
0
{
406
0
ccontext->stack_guard = guard;
407
0
ccontext->stack_guard_data = user_data;
408
0
return 0;
409
0
}
410
411
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
412
pcre2_set_optimize(pcre2_compile_context *ccontext, uint32_t directive)
413
0
{
414
0
if (ccontext == NULL)
415
0
  return PCRE2_ERROR_NULL;
416
417
0
switch (directive)
418
0
  {
419
0
  case PCRE2_OPTIMIZATION_NONE:
420
0
  ccontext->optimization_flags = 0;
421
0
  break;
422
423
0
  case PCRE2_OPTIMIZATION_FULL:
424
0
  ccontext->optimization_flags = PCRE2_OPTIMIZATION_ALL;
425
0
  break;
426
427
0
  default:
428
0
  if (directive >= PCRE2_AUTO_POSSESS && directive <= PCRE2_START_OPTIMIZE_OFF)
429
0
    {
430
    /* Even directive numbers starting from 64 switch a bit on;
431
     * Odd directive numbers starting from 65 switch a bit off */
432
0
    if ((directive & 1) != 0)
433
0
      ccontext->optimization_flags &= ~(1u << ((directive >> 1) - 32));
434
0
    else
435
0
      ccontext->optimization_flags |= 1u << ((directive >> 1) - 32);
436
0
    return 0;
437
0
    }
438
0
  return PCRE2_ERROR_BADOPTION;
439
0
  }
440
441
0
return 0;
442
0
}
443
444
/* ------------ Match context ------------ */
445
446
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
447
pcre2_set_callout(pcre2_match_context *mcontext,
448
  int (*callout)(pcre2_callout_block *, void *), void *callout_data)
449
36.4k
{
450
36.4k
mcontext->callout = callout;
451
36.4k
mcontext->callout_data = callout_data;
452
36.4k
return 0;
453
36.4k
}
454
455
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
456
pcre2_set_substitute_callout(pcre2_match_context *mcontext,
457
  int (*substitute_callout)(pcre2_substitute_callout_block *, void *),
458
  void *substitute_callout_data)
459
0
{
460
0
mcontext->substitute_callout = substitute_callout;
461
0
mcontext->substitute_callout_data = substitute_callout_data;
462
0
return 0;
463
0
}
464
465
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
466
pcre2_set_substitute_case_callout(pcre2_match_context *mcontext,
467
  PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,
468
                                        PCRE2_SIZE, int, void *),
469
  void *substitute_case_callout_data)
470
0
{
471
0
mcontext->substitute_case_callout = substitute_case_callout;
472
0
mcontext->substitute_case_callout_data = substitute_case_callout_data;
473
0
return 0;
474
0
}
475
476
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
477
pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)
478
0
{
479
0
mcontext->heap_limit = limit;
480
0
return 0;
481
0
}
482
483
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
484
pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
485
36.4k
{
486
36.4k
mcontext->match_limit = limit;
487
36.4k
return 0;
488
36.4k
}
489
490
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
491
pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
492
36.4k
{
493
36.4k
mcontext->depth_limit = limit;
494
36.4k
return 0;
495
36.4k
}
496
497
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
498
pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
499
0
{
500
0
mcontext->offset_limit = limit;
501
0
return 0;
502
0
}
503
504
/* These functions became obsolete at release 10.30. The first is kept as a
505
synonym for backwards compatibility. The second now does nothing. */
506
507
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
508
pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
509
0
{
510
0
return pcre2_set_depth_limit(mcontext, limit);
511
0
}
512
513
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
514
pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
515
  void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
516
  void *mydata)
517
0
{
518
0
(void)mcontext;
519
0
(void)mymalloc;
520
0
(void)myfree;
521
0
(void)mydata;
522
0
return 0;
523
0
}
524
525
526
/* ------------ Convert context ------------ */
527
528
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
529
pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)
530
0
{
531
0
if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&
532
0
    separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;
533
0
ccontext->glob_separator = separator;
534
0
return 0;
535
0
}
536
537
static const char *globpunct =
538
  STR_EXCLAMATION_MARK STR_QUOTATION_MARK STR_NUMBER_SIGN STR_DOLLAR_SIGN
539
  STR_PERCENT_SIGN STR_AMPERSAND STR_APOSTROPHE STR_LEFT_PARENTHESIS
540
  STR_RIGHT_PARENTHESIS STR_ASTERISK STR_PLUS STR_COMMA STR_MINUS STR_DOT
541
  STR_SLASH STR_COLON STR_SEMICOLON STR_LESS_THAN_SIGN STR_EQUALS_SIGN
542
  STR_GREATER_THAN_SIGN STR_QUESTION_MARK STR_COMMERCIAL_AT
543
  STR_LEFT_SQUARE_BRACKET STR_BACKSLASH STR_RIGHT_SQUARE_BRACKET
544
  STR_CIRCUMFLEX_ACCENT STR_UNDERSCORE STR_GRAVE_ACCENT STR_LEFT_CURLY_BRACKET
545
  STR_VERTICAL_LINE STR_RIGHT_CURLY_BRACKET STR_TILDE;
546
547
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
548
pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
549
0
{
550
0
if (escape > 255 || (escape != 0 && strchr(globpunct, escape) == NULL))
551
0
  return PCRE2_ERROR_BADDATA;
552
0
ccontext->glob_escape = escape;
553
0
return 0;
554
0
}
555
556
/* End of pcre2_context.c */
557