Skip to content

Commit 183e8a9

Browse files
committed
Add check for ridiculous offsets to substring extraction functions.
1 parent ce5b604 commit 183e8a9

File tree

7 files changed

+14
-0
lines changed

7 files changed

+14
-0
lines changed

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ patterns.
150150
a recursion, pcre2_match() misbehaved and gave the wrong match. For example,
151151
the pattern /|a(?0)/ matched against "aaaa".
152152

153+
39. Add a test for ridiculous ovector offset values to the substring extraction
154+
functions.
155+
153156

154157
Version 10.42 11-December-2022
155158
------------------------------

src/pcre2.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ released, the numbers must not be changed. */
405405
#define PCRE2_ERROR_CONVERT_SYNTAX (-64)
406406
#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)
407407
#define PCRE2_ERROR_DFA_UINVALID_UTF (-66)
408+
#define PCRE2_ERROR_INVALIDOFFSET (-67)
408409

409410

410411
/* Request types for pcre2_pattern_info() */

src/pcre2_dfa_match.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,7 @@ for (;;)
40134013
match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
40144014
match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
40154015
}
4016+
match_data->subject_length = length;
40164017
match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
40174018
match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject);
40184019
match_data->startchar = (PCRE2_SIZE)(start_match - subject);

src/pcre2_error.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static const unsigned char match_error_texts[] =
274274
/* 65 */
275275
"internal error - duplicate substitution match\0"
276276
"PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"
277+
"INTERNAL ERROR: invalid substring offset\0"
277278
;
278279

279280

src/pcre2_intmodedep.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ typedef struct pcre2_real_match_data {
659659
PCRE2_SPTR mark; /* Pointer to last mark */
660660
struct heapframe *heapframes; /* Backtracking frames heap memory */
661661
PCRE2_SIZE heapframes_size; /* Malloc-ed size */
662+
PCRE2_SIZE subject_length; /* Subject length */
662663
PCRE2_SIZE leftchar; /* Offset to leftmost code unit */
663664
PCRE2_SIZE rightchar; /* Offset to rightmost code unit */
664665
PCRE2_SIZE startchar; /* Offset to starting code unit */

src/pcre2_match.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6669,6 +6669,7 @@ if (use_jit)
66696669
match_data, mcontext);
66706670
if (rc != PCRE2_ERROR_JIT_BADOPTION)
66716671
{
6672+
match_data->subject_length = length;
66726673
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
66736674
{
66746675
length = CU2BYTES(length + was_zero_terminated);
@@ -7603,6 +7604,7 @@ if (rc == MATCH_MATCH)
76037604
{
76047605
match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
76057606
0 : (int)mb->end_offset_top/2 + 1;
7607+
match_data->subject_length = length;
76067608
match_data->startchar = start_match - subject;
76077609
match_data->leftchar = mb->start_used_ptr - subject;
76087610
match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
@@ -7617,6 +7619,7 @@ if (rc == MATCH_MATCH)
76177619
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
76187620
}
76197621
else match_data->subject = subject;
7622+
76207623
return match_data->rc;
76217624
}
76227625

@@ -7638,6 +7641,7 @@ PCRE2_ERROR_PARTIAL. */
76387641
else if (match_partial != NULL)
76397642
{
76407643
match_data->subject = subject;
7644+
match_data->subject_length = length;
76417645
match_data->ovector[0] = match_partial - subject;
76427646
match_data->ovector[1] = end_subject - subject;
76437647
match_data->startchar = match_partial - subject;

src/pcre2_substring.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ Returns: if successful: 0
309309
PCRE2_ERROR_NOSUBSTRING: no such substring
310310
PCRE2_ERROR_UNAVAILABLE: ovector is too small
311311
PCRE2_ERROR_UNSET: substring is not set
312+
PCRE2_ERROR_INVALIDOFFSET: internal error, should not occur
312313
*/
313314

314315
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
@@ -341,6 +342,8 @@ else /* Matched using pcre2_dfa_match() */
341342

342343
left = match_data->ovector[stringnumber*2];
343344
right = match_data->ovector[stringnumber*2+1];
345+
if (left > match_data->subject_length || right > match_data->subject_length)
346+
return PCRE2_ERROR_INVALIDOFFSET;
344347
if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;
345348
return 0;
346349
}

0 commit comments

Comments
 (0)