Skip to content

Commit c210f7c

Browse files
authored
Avoid zero-length allocations, which return NULL on z/OS (#810)
It's totally legal to return NULL for malloc(0), but every other platform that we target returns a non-NULL pointer. We don't need to do an allocation anyway (nor do we need to copy the terminating NUL byte).
1 parent bbb7436 commit c210f7c

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

src/pcre2_dfa_match.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,7 +3342,6 @@ pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
33423342
pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
33433343
{
33443344
int rc;
3345-
int was_zero_terminated = 0;
33463345

33473346
const pcre2_real_code *re = (const pcre2_real_code *)code;
33483347
uint32_t original_options = options;
@@ -3403,7 +3402,6 @@ if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0)
34033402
if (length == PCRE2_ZERO_TERMINATED)
34043403
{
34053404
length = PRIV(strlen)(subject);
3406-
was_zero_terminated = 1;
34073405
}
34083406

34093407
if (wscount < 20) { rc = PCRE2_ERROR_DFA_WSSIZE; goto EXIT; }
@@ -4062,11 +4060,16 @@ for (;;)
40624060

40634061
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
40644062
{
4065-
length = CU2BYTES(length + was_zero_terminated);
4066-
match_data->subject = match_data->memctl.malloc(length,
4067-
match_data->memctl.memory_data);
4068-
if (match_data->subject == NULL) { rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }
4069-
memcpy((void *)match_data->subject, subject, length);
4063+
if (length != 0)
4064+
{
4065+
match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
4066+
match_data->memctl.memory_data);
4067+
if (match_data->subject == NULL)
4068+
{ rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }
4069+
memcpy((void *)match_data->subject, subject, CU2BYTES(length));
4070+
}
4071+
else
4072+
match_data->subject = NULL;
40704073
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
40714074
}
40724075
else if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)

src/pcre2_match.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6948,7 +6948,6 @@ pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
69486948
pcre2_match_context *mcontext)
69496949
{
69506950
int rc;
6951-
int was_zero_terminated = 0;
69526951
const uint8_t *start_bits = NULL;
69536952
const pcre2_real_code *re = (const pcre2_real_code *)code;
69546953
uint32_t original_options = options;
@@ -7024,7 +7023,6 @@ req_cu_ptr = start_match - 1;
70247023
if (length == PCRE2_ZERO_TERMINATED)
70257024
{
70267025
length = PRIV(strlen)(subject);
7027-
was_zero_terminated = 1;
70287026
}
70297027
true_end_subject = end_subject = subject + length;
70307028

@@ -7193,12 +7191,16 @@ if (use_jit)
71937191
match_data->options = original_options;
71947192
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
71957193
{
7196-
length = CU2BYTES(length + was_zero_terminated);
7197-
match_data->subject = match_data->memctl.malloc(length,
7198-
match_data->memctl.memory_data);
7199-
if (match_data->subject == NULL)
7200-
return match_data->rc = PCRE2_ERROR_NOMEMORY;
7201-
memcpy((void *)match_data->subject, subject, length);
7194+
if (length != 0)
7195+
{
7196+
match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
7197+
match_data->memctl.memory_data);
7198+
if (match_data->subject == NULL)
7199+
return match_data->rc = PCRE2_ERROR_NOMEMORY;
7200+
memcpy((void *)match_data->subject, subject, CU2BYTES(length));
7201+
}
7202+
else
7203+
match_data->subject = NULL;
72027204
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
72037205
}
72047206
else
@@ -8155,12 +8157,16 @@ if (rc == MATCH_MATCH)
81558157
mb->last_used_ptr : mb->end_match_ptr) - subject;
81568158
if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
81578159
{
8158-
length = CU2BYTES(length + was_zero_terminated);
8159-
match_data->subject = match_data->memctl.malloc(length,
8160-
match_data->memctl.memory_data);
8161-
if (match_data->subject == NULL)
8162-
return match_data->rc = PCRE2_ERROR_NOMEMORY;
8163-
memcpy((void *)match_data->subject, subject, length);
8160+
if (length != 0)
8161+
{
8162+
match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
8163+
match_data->memctl.memory_data);
8164+
if (match_data->subject == NULL)
8165+
return match_data->rc = PCRE2_ERROR_NOMEMORY;
8166+
memcpy((void *)match_data->subject, subject, CU2BYTES(length));
8167+
}
8168+
else
8169+
match_data->subject = NULL;
81648170
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
81658171
}
81668172
else match_data->subject = original_subject;

src/pcre2test_inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,6 +2533,7 @@ if (pat_patctl.convert_type != CONVERT_UNSET)
25332533

25342534
// TODO No valgrind guards for out-of-bounds read in pcre2_pattern_convert(),
25352535
// nor do we appear to have a facility for testing zero-terminated patterns here.
2536+
// Can we use something other than zero as a sentinel to allow testing empty inputs?
25362537

25372538
if (pat_patctl.convert_length != 0)
25382539
{

0 commit comments

Comments
 (0)