Skip to content

Commit a35c278

Browse files
IsaacOscarNWilson
andauthored
Store NULL in match_data->subject when subject was NULL.
Previously, match_data->subject would store a pointer to a stack allocated string, but that pointer would be dangling as soon as pcre2_match/pcre2_dfa_match returned. These pointers were than memcpy'd (with a size of 0), which is technically undefined behaviour, despite ot causing any observable problems, even with valgrind. (cherry picked from commit d714d98) Co-authored-by: Nicholas Wilson <[email protected]>
1 parent f5afbeb commit a35c278

File tree

7 files changed

+42
-6
lines changed

7 files changed

+42
-6
lines changed

src/pcre2_dfa_match.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,7 @@ int was_zero_terminated = 0;
33473347
const pcre2_real_code *re = (const pcre2_real_code *)code;
33483348

33493349
PCRE2_UCHAR null_str[1] = { 0xcd };
3350+
PCRE2_SPTR original_subject = subject;
33503351
PCRE2_SPTR start_match;
33513352
PCRE2_SPTR end_subject;
33523353
PCRE2_SPTR bumpalong_limit;
@@ -4059,7 +4060,8 @@ for (;;)
40594060
}
40604061
else
40614062
{
4062-
if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL) match_data->subject = subject;
4063+
if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)
4064+
match_data->subject = original_subject;
40634065
}
40644066
goto EXIT;
40654067
}

src/pcre2_match.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6969,6 +6969,7 @@ PCRE2_UCHAR req_cu = 0;
69696969
PCRE2_UCHAR req_cu2 = 0;
69706970

69716971
PCRE2_UCHAR null_str[1] = { 0xcd };
6972+
PCRE2_SPTR original_subject = subject;
69726973
PCRE2_SPTR bumpalong_limit;
69736974
PCRE2_SPTR end_subject;
69746975
PCRE2_SPTR true_end_subject;
@@ -7184,7 +7185,6 @@ if (use_jit)
71847185
match_data, mcontext);
71857186
if (rc != PCRE2_ERROR_JIT_BADOPTION)
71867187
{
7187-
match_data->subject_length = length;
71887188
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
71897189
{
71907190
length = CU2BYTES(length + was_zero_terminated);
@@ -7194,6 +7194,12 @@ if (use_jit)
71947194
memcpy((void *)match_data->subject, subject, length);
71957195
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
71967196
}
7197+
else
7198+
{
7199+
/* When pcre2_jit_match sets the subject, it doesn't know what the
7200+
original passed-in pointer was. */
7201+
if (match_data->subject != NULL) match_data->subject = original_subject;
7202+
}
71977203
return rc;
71987204
}
71997205
}
@@ -8148,7 +8154,7 @@ if (rc == MATCH_MATCH)
81488154
memcpy((void *)match_data->subject, subject, length);
81498155
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
81508156
}
8151-
else match_data->subject = subject;
8157+
else match_data->subject = original_subject;
81528158

81538159
return match_data->rc;
81548160
}
@@ -8170,7 +8176,7 @@ PCRE2_ERROR_PARTIAL. */
81708176

81718177
else if (match_partial != NULL)
81728178
{
8173-
match_data->subject = subject;
8179+
match_data->subject = original_subject;
81748180
match_data->subject_length = length;
81758181
match_data->start_offset = start_offset;
81768182
match_data->ovector[0] = match_partial - subject;

src/pcre2_substring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ PCRE2_SIZE size;
122122
rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
123123
if (rc < 0) return rc;
124124
if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;
125-
memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
125+
if (size != 0) memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
126126
CU2BYTES(size));
127127
buffer[size] = 0;
128128
*sizeptr = size;
@@ -214,7 +214,7 @@ yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
214214
(size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
215215
if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
216216
yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
217-
memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
217+
if (size != 0) memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
218218
CU2BYTES(size));
219219
yield[size] = 0;
220220
*stringptr = yield;

testdata/testinput2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8113,4 +8113,8 @@ a)"xI
81138113
foo\=copy_matched_subject
81148114
foo\=global,copy_matched_subject
81158115

8116+
# Tests for reading matches from NULL subjects
8117+
/(.?)/
8118+
\=null_subject,copy=0,copy=1,get=0,get=1,getall
8119+
81168120
# End of testinput2

testdata/testinput6

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5251,4 +5251,8 @@
52515251
/^(?1(2))(?(DEFINE)(a(.)b))/
52525252
axb
52535253

5254+
# Tests for reading matches from NULL subjects
5255+
/(.?)/
5256+
\=null_subject,copy=0,get=0,getall
5257+
52545258
# End of testinput6

testdata/testoutput2

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23241,6 +23241,18 @@ Failed: error -51: NULL argument passed with non-zero length
2324123241
foo\=global,copy_matched_subject
2324223242
1: bar
2324323243

23244+
# Tests for reading matches from NULL subjects
23245+
/(.?)/
23246+
\=null_subject,copy=0,copy=1,get=0,get=1,getall
23247+
0:
23248+
1:
23249+
0C (0)
23250+
1C (0)
23251+
0G (0)
23252+
1G (0)
23253+
0L
23254+
1L
23255+
2324423256
# End of testinput2
2324523257
Error -80: PCRE2_ERROR_BADDATA (unknown error number)
2324623258
Error -62: bad serialized data

testdata/testoutput6

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8218,4 +8218,12 @@ No match
82188218
axb
82198219
Failed: error -42: pattern contains an item that is not supported for DFA matching
82208220

8221+
# Tests for reading matches from NULL subjects
8222+
/(.?)/
8223+
\=null_subject,copy=0,get=0,getall
8224+
0:
8225+
0C (0)
8226+
0G (0)
8227+
0L
8228+
82218229
# End of testinput6

0 commit comments

Comments
 (0)