Skip to content

Commit b0cea02

Browse files
IsaacOscarNWilson
andauthored
Store return codes in match_data.
This makes match_data->rc after a call to pcre2_match, pcre2_jit_match, and pcre2_dfa_match nire reliable, so that pcre2_substitute with PCRE2_SUBSTITUTE_MATCHED can abort early. (cherry picked from commit 1796fb2) Co-authored-by: Nicholas Wilson <[email protected]>
1 parent a35c278 commit b0cea02

File tree

3 files changed

+55
-47
lines changed

3 files changed

+55
-47
lines changed

src/pcre2_dfa_match.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,40 +3393,43 @@ if (subject == NULL && length == 0) subject = null_str;
33933393

33943394
/* Plausibility checks */
33953395

3396-
if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
3397-
if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
3398-
return PCRE2_ERROR_NULL;
3396+
if (match_data == NULL) return PCRE2_ERROR_NULL;
3397+
if (re == NULL || subject == NULL || workspace == NULL)
3398+
{ rc = PCRE2_ERROR_NULL; goto EXIT; }
3399+
if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0)
3400+
{ rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
33993401

34003402
if (length == PCRE2_ZERO_TERMINATED)
34013403
{
34023404
length = PRIV(strlen)(subject);
34033405
was_zero_terminated = 1;
34043406
}
34053407

3406-
if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
3407-
if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
3408+
if (wscount < 20) { rc = PCRE2_ERROR_DFA_WSSIZE; goto EXIT; }
3409+
if (start_offset > length) { rc = PCRE2_ERROR_BADOFFSET; goto EXIT; }
34083410

34093411
/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
34103412
time. */
34113413

34123414
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
34133415
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
3414-
return PCRE2_ERROR_BADOPTION;
3416+
{ rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
34153417

34163418
/* Invalid UTF support is not available for DFA matching. */
34173419

34183420
if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
3419-
return PCRE2_ERROR_DFA_UINVALID_UTF;
3421+
{ rc = PCRE2_ERROR_DFA_UINVALID_UTF; goto EXIT; }
34203422

34213423
/* Check that the first field in the block is the magic number. If it is not,
34223424
return with PCRE2_ERROR_BADMAGIC. */
34233425

3424-
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
3426+
if (re->magic_number != MAGIC_NUMBER)
3427+
{ rc = PCRE2_ERROR_BADMAGIC; goto EXIT; }
34253428

34263429
/* Check the code unit width. */
34273430

34283431
if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
3429-
return PCRE2_ERROR_BADMODE;
3432+
{ rc = PCRE2_ERROR_BADMODE; goto EXIT; }
34303433

34313434
/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
34323435
options variable for this function. Users of PCRE2 who are not calling the
@@ -3452,8 +3455,8 @@ of the workspace. */
34523455
if ((options & PCRE2_DFA_RESTART) != 0)
34533456
{
34543457
if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
3455-
workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
3456-
return PCRE2_ERROR_DFA_BADRESTART;
3458+
workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
3459+
{ rc = PCRE2_ERROR_DFA_BADRESTART; goto EXIT; }
34573460
}
34583461

34593462
/* Set some local values */
@@ -3501,7 +3504,7 @@ else
35013504
if (mcontext->offset_limit != PCRE2_UNSET)
35023505
{
35033506
if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
3504-
return PCRE2_ERROR_BADOFFSETLIMIT;
3507+
{ rc = PCRE2_ERROR_BADOFFSETLIMIT; goto EXIT; }
35053508
bumpalong_limit = subject + mcontext->offset_limit;
35063509
}
35073510
mb->callout = mcontext->callout;
@@ -3571,7 +3574,8 @@ switch(re->newline_convention)
35713574
/* LCOV_EXCL_START */
35723575
default:
35733576
PCRE2_DEBUG_UNREACHABLE();
3574-
return PCRE2_ERROR_INTERNAL;
3577+
rc = PCRE2_ERROR_INTERNAL;
3578+
goto EXIT;
35753579
/* LCOV_EXCL_STOP */
35763580
}
35773581

@@ -3593,7 +3597,7 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
35933597
#if PCRE2_CODE_UNIT_WIDTH != 32
35943598
unsigned int i;
35953599
if (start_match < end_subject && NOT_FIRSTCU(*start_match))
3596-
return PCRE2_ERROR_BADUTFOFFSET;
3600+
{ rc = PCRE2_ERROR_BADUTFOFFSET; goto EXIT; }
35973601
for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
35983602
{
35993603
check_subject--;
@@ -3614,12 +3618,12 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
36143618
/* Validate the relevant portion of the subject. After an error, adjust the
36153619
offset to be an absolute offset in the whole string. */
36163620

3617-
match_data->rc = PRIV(valid_utf)(check_subject,
3621+
rc = PRIV(valid_utf)(check_subject,
36183622
length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));
3619-
if (match_data->rc != 0)
3623+
if (rc != 0)
36203624
{
36213625
match_data->startchar += (PCRE2_SIZE)(check_subject - subject);
3622-
return match_data->rc;
3626+
goto EXIT;
36233627
}
36243628
}
36253629
#endif /* SUPPORT_UNICODE */
@@ -4047,14 +4051,13 @@ for (;;)
40474051
match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
40484052
match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);
40494053
match_data->startchar = (PCRE2_SIZE)(start_match - subject);
4050-
match_data->rc = rc;
40514054

40524055
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
40534056
{
40544057
length = CU2BYTES(length + was_zero_terminated);
40554058
match_data->subject = match_data->memctl.malloc(length,
40564059
match_data->memctl.memory_data);
4057-
if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
4060+
if (match_data->subject == NULL) { rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }
40584061
memcpy((void *)match_data->subject, subject, length);
40594062
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
40604063
}
@@ -4105,6 +4108,7 @@ while (rws->next != NULL)
41054108
mb->memctl.free(next, mb->memctl.memory_data);
41064109
}
41074110

4111+
match_data->rc = rc;
41084112
return rc;
41094113
}
41104114

src/pcre2_jit_match_inc.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,8 @@ pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
9999
(void)length;
100100
(void)start_offset;
101101
(void)options;
102-
(void)match_data;
103102
(void)mcontext;
104-
return PCRE2_ERROR_JIT_BADOPTION;
103+
return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;
105104

106105
#else /* SUPPORT_JIT */
107106

@@ -124,7 +123,7 @@ else if ((options & PCRE2_PARTIAL_SOFT) != 0)
124123
index = 1;
125124

126125
if (functions == NULL || functions->executable_funcs[index] == NULL)
127-
return PCRE2_ERROR_JIT_BADOPTION;
126+
return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;
128127

129128
/* Sanity checks should be handled by pcre2_match. */
130129
arguments.str = subject + start_offset;

src/pcre2_match.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7012,9 +7012,11 @@ if (subject == NULL && length == 0) subject = null_str;
70127012

70137013
/* Plausibility checks */
70147014

7015-
if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
7016-
if (code == NULL || subject == NULL || match_data == NULL)
7017-
return PCRE2_ERROR_NULL;
7015+
if (match_data == NULL) return PCRE2_ERROR_NULL;
7016+
if (code == NULL || subject == NULL)
7017+
return match_data->rc = PCRE2_ERROR_NULL;
7018+
if ((options & ~PUBLIC_MATCH_OPTIONS) != 0)
7019+
return match_data->rc = PCRE2_ERROR_BADOPTION;
70187020

70197021
start_match = subject + start_offset;
70207022
req_cu_ptr = start_match - 1;
@@ -7025,16 +7027,17 @@ if (length == PCRE2_ZERO_TERMINATED)
70257027
}
70267028
true_end_subject = end_subject = subject + length;
70277029

7028-
if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
7030+
if (start_offset > length) return match_data->rc = PCRE2_ERROR_BADOFFSET;
70297031

70307032
/* Check that the first field in the block is the magic number. */
70317033

7032-
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
7034+
if (re->magic_number != MAGIC_NUMBER)
7035+
return match_data->rc = PCRE2_ERROR_BADMAGIC;
70337036

70347037
/* Check the code unit width. */
70357038

70367039
if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
7037-
return PCRE2_ERROR_BADMODE;
7040+
return match_data->rc = PCRE2_ERROR_BADMODE;
70387041

70397042
/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
70407043
options variable for this function. Users of PCRE2 who are not calling the
@@ -7081,14 +7084,14 @@ time. */
70817084

70827085
if (mb->partial != 0 &&
70837086
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
7084-
return PCRE2_ERROR_BADOPTION;
7087+
return match_data->rc = PCRE2_ERROR_BADOPTION;
70857088

70867089
/* It is an error to set an offset limit without setting the flag at compile
70877090
time. */
70887091

70897092
if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
70907093
(re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
7091-
return PCRE2_ERROR_BADOFFSETLIMIT;
7094+
return match_data->rc = PCRE2_ERROR_BADOFFSETLIMIT;
70927095

70937096
/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
70947097
free the memory that was obtained. Set the field to NULL for no match cases. */
@@ -7128,11 +7131,11 @@ if (use_jit)
71287131
#if PCRE2_CODE_UNIT_WIDTH != 32
71297132
if (start_match < end_subject && NOT_FIRSTCU(*start_match))
71307133
{
7131-
if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
7134+
if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;
71327135
#if PCRE2_CODE_UNIT_WIDTH == 8
7133-
return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
7136+
return match_data->rc = PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
71347137
#else
7135-
return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
7138+
return match_data->rc = PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
71367139
#endif
71377140
}
71387141
#endif /* WIDTH != 32 */
@@ -7167,12 +7170,12 @@ if (use_jit)
71677170
/* Validate the relevant portion of the subject. Adjust the offset of an
71687171
invalid code point to be an absolute offset in the whole string. */
71697172

7170-
match_data->rc = PRIV(valid_utf)(start_match,
7173+
rc = PRIV(valid_utf)(start_match,
71717174
length - (start_match - subject), &(match_data->startchar));
7172-
if (match_data->rc != 0)
7175+
if (rc != 0)
71737176
{
71747177
match_data->startchar += start_match - subject;
7175-
return match_data->rc;
7178+
return match_data->rc = rc;
71767179
}
71777180
jit_checked_utf = TRUE;
71787181
}
@@ -7190,7 +7193,8 @@ if (use_jit)
71907193
length = CU2BYTES(length + was_zero_terminated);
71917194
match_data->subject = match_data->memctl.malloc(length,
71927195
match_data->memctl.memory_data);
7193-
if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
7196+
if (match_data->subject == NULL)
7197+
return match_data->rc = PCRE2_ERROR_NOMEMORY;
71947198
memcpy((void *)match_data->subject, subject, length);
71957199
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
71967200
}
@@ -7256,11 +7260,11 @@ if (utf &&
72567260
}
72577261
else if (start_match < end_subject && NOT_FIRSTCU(*start_match))
72587262
{
7259-
if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
7263+
if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;
72607264
#if PCRE2_CODE_UNIT_WIDTH == 8
7261-
return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
7265+
return match_data->rc = PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
72627266
#else
7263-
return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
7267+
return match_data->rc = PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
72647268
#endif
72657269
}
72667270
#endif /* WIDTH != 32 */
@@ -7308,18 +7312,18 @@ if (utf &&
73087312

73097313
for (;;)
73107314
{
7311-
match_data->rc = PRIV(valid_utf)(mb->check_subject,
7315+
rc = PRIV(valid_utf)(mb->check_subject,
73127316
length - (mb->check_subject - subject), &(match_data->startchar));
73137317

7314-
if (match_data->rc == 0) break; /* Valid UTF string */
7318+
if (rc == 0) break; /* Valid UTF string */
73157319

73167320
/* Invalid UTF string. Adjust the offset to be an absolute offset in the
73177321
whole string. If we are handling invalid UTF strings, set end_subject to
73187322
stop before the bad code unit, and set the options to "not end of line".
73197323
Otherwise return the error. */
73207324

73217325
match_data->startchar += mb->check_subject - subject;
7322-
if (!allow_invalid || match_data->rc > 0) return match_data->rc;
7326+
if (!allow_invalid || rc > 0) return match_data->rc = rc;
73237327
end_subject = subject + match_data->startchar;
73247328

73257329
/* If the end precedes start_match, it means there is invalid UTF in the
@@ -7436,7 +7440,7 @@ switch(re->newline_convention)
74367440
/* LCOV_EXCL_START */
74377441
default:
74387442
PCRE2_DEBUG_UNREACHABLE();
7439-
return PCRE2_ERROR_INTERNAL;
7443+
return match_data->rc = PCRE2_ERROR_INTERNAL;
74407444
/* LCOV_EXCL_STOP */
74417445
}
74427446

@@ -7479,7 +7483,7 @@ if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
74797483
if (heapframes_size / 1024 > mb->heap_limit)
74807484
{
74817485
PCRE2_SIZE max_size = 1024 * mb->heap_limit;
7482-
if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT;
7486+
if (max_size < frame_size) return match_data->rc = PCRE2_ERROR_HEAPLIMIT;
74837487
heapframes_size = max_size;
74847488
}
74857489

@@ -7495,7 +7499,7 @@ if (match_data->heapframes_size < heapframes_size)
74957499
if (match_data->heapframes == NULL)
74967500
{
74977501
match_data->heapframes_size = 0;
7498-
return PCRE2_ERROR_NOMEMORY;
7502+
return match_data->rc = PCRE2_ERROR_NOMEMORY;
74997503
}
75007504
match_data->heapframes_size = heapframes_size;
75017505
}
@@ -8150,7 +8154,8 @@ if (rc == MATCH_MATCH)
81508154
length = CU2BYTES(length + was_zero_terminated);
81518155
match_data->subject = match_data->memctl.malloc(length,
81528156
match_data->memctl.memory_data);
8153-
if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
8157+
if (match_data->subject == NULL)
8158+
return match_data->rc = PCRE2_ERROR_NOMEMORY;
81548159
memcpy((void *)match_data->subject, subject, length);
81558160
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
81568161
}

0 commit comments

Comments
 (0)