Give match data memory failur in regcomp() instead of regexec()

This commit is contained in:
Philip.Hazel 2015-11-12 18:35:49 +00:00
parent 8d70b1d368
commit 2f8febd4b1
3 changed files with 30 additions and 17 deletions

View File

@ -293,6 +293,9 @@ a factor of the size of the compiling workspace (it currently is).
86. Avoid the possibility of computing with an out-of-bounds pointer (though 86. Avoid the possibility of computing with an out-of-bounds pointer (though
not dereferencing it) while handling lookbehind assertions. not dereferencing it) while handling lookbehind assertions.
87. Failure to get memory for the match data in regcomp() is now given as a
regcomp() error instead of waiting for regexec() to pick it up.
Version 10.20 30-June-2015 Version 10.20 30-June-2015
-------------------------- --------------------------

View File

@ -152,15 +152,15 @@ message = (errcode <= 0 || errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
if (preg != NULL && (int)preg->re_erroffset != -1) if (preg != NULL && (int)preg->re_erroffset != -1)
{ {
used = snprintf(errbuf, errbuf_size, "%s at offset %-6d", message, used = snprintf(errbuf, errbuf_size, "%s at offset %-6d", message,
(int)preg->re_erroffset); (int)preg->re_erroffset);
} }
else else
{ {
used = snprintf(errbuf, errbuf_size, "%s", message); used = snprintf(errbuf, errbuf_size, "%s", message);
} }
return used + 1; return used + 1;
} }
@ -231,6 +231,13 @@ if (preg->re_pcre2_code == NULL)
preg->re_nsub = (size_t)re_nsub; preg->re_nsub = (size_t)re_nsub;
if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) re_nsub = -1; if ((options & PCRE2_NO_AUTO_CAPTURE) != 0) re_nsub = -1;
preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL); preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL);
if (preg->re_match_data == NULL)
{
pcre2_code_free(preg->re_pcre2_code);
return REG_ESPACE;
}
return 0; return 0;
} }

View File

@ -445,7 +445,7 @@ typedef struct patctl { /* Structure for pattern modifiers. */
uint32_t jit; uint32_t jit;
uint32_t stackguard_test; uint32_t stackguard_test;
uint32_t tables_id; uint32_t tables_id;
uint32_t regerror_buffsize; uint32_t regerror_buffsize;
uint8_t locale[LOCALESIZE]; uint8_t locale[LOCALESIZE];
} patctl; } patctl;
@ -4427,7 +4427,7 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0)
uint8_t *pc = pp; uint8_t *pc = pp;
uint32_t count = 1; uint32_t count = 1;
size_t length = 1; size_t length = 1;
/* Check for replication syntax; if not found, the defaults just set will /* Check for replication syntax; if not found, the defaults just set will
prevail and one character will be copied. */ prevail and one character will be copied. */
@ -4453,23 +4453,23 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0)
count = i; count = i;
length = clen; length = clen;
pp = pe; pp = pe;
break; break;
} }
} }
} }
} }
/* Add to output. If the buffer is too small expand it. The function for /* Add to output. If the buffer is too small expand it. The function for
expanding buffers always keeps buffer and pbuffer8 in step as far as their expanding buffers always keeps buffer and pbuffer8 in step as far as their
size goes. */ size goes. */
while (pt + count * length > pbuffer8 + pbuffer8_size) while (pt + count * length > pbuffer8 + pbuffer8_size)
{ {
size_t pc_offset = pc - buffer; size_t pc_offset = pc - buffer;
size_t pp_offset = pp - buffer; size_t pp_offset = pp - buffer;
size_t pt_offset = pt - pbuffer8; size_t pt_offset = pt - pbuffer8;
expand_input_buffers(); expand_input_buffers();
pc = buffer + pc_offset; pc = buffer + pc_offset;
pp = buffer + pp_offset; pp = buffer + pp_offset;
pt = pbuffer8 + pt_offset; pt = pbuffer8 + pt_offset;
} }
@ -4483,9 +4483,9 @@ else if ((pat_patctl.control & CTL_EXPAND) != 0)
*pt = 0; *pt = 0;
patlen = pt - pbuffer8; patlen = pt - pbuffer8;
if ((pat_patctl.control & CTL_INFO) != 0) if ((pat_patctl.control & CTL_INFO) != 0)
fprintf(outfile, "Expanded: %s\n", pbuffer8); fprintf(outfile, "Expanded: %s\n", pbuffer8);
} }
/* Neither hex nor expanded, just copy the input verbatim. */ /* Neither hex nor expanded, just copy the input verbatim. */
@ -4596,20 +4596,23 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
if (rc != 0) /* Failure */ if (rc != 0) /* Failure */
{ {
size_t bsize, usize; size_t bsize, usize;
preg.re_pcre2_code = NULL; /* In case something was left in there */
preg.re_match_data = NULL;
bsize = (pat_patctl.regerror_buffsize != 0)? bsize = (pat_patctl.regerror_buffsize != 0)?
pat_patctl.regerror_buffsize : pbuffer8_size; pat_patctl.regerror_buffsize : pbuffer8_size;
if (bsize + 8 < pbuffer8_size) if (bsize + 8 < pbuffer8_size)
memcpy(pbuffer8 + bsize, "DEADBEEF", 8); memcpy(pbuffer8 + bsize, "DEADBEEF", 8);
usize = regerror(rc, &preg, (char *)pbuffer8, bsize); usize = regerror(rc, &preg, (char *)pbuffer8, bsize);
fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, pbuffer8); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, pbuffer8);
if (usize > bsize) if (usize > bsize)
{ {
fprintf(outfile, "** regerror() message truncated\n"); fprintf(outfile, "** regerror() message truncated\n");
if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0) if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0)
fprintf(outfile, "** regerror() buffer overflow\n"); fprintf(outfile, "** regerror() buffer overflow\n");
} }
return PR_SKIP; return PR_SKIP;
} }
return PR_OK; return PR_OK;