Skip to content

Commit

Permalink
pcre2test: memory reports only compiled memory usage for code/data (#418
Browse files Browse the repository at this point in the history
)

Since 05aafb2 (Implement pcre2_set_max_pattern_compiled_length() and set
this limit in the fuzzer, 2024-04-24), the memory modifier has reported
the full size of the allocated "code" returned by `pcre2_compile`.

Problem is that the size of the structure used to hold that in memory also
depends on the platform ABI and even alignment by the compiler, and has
been therefore fragile to compare.

Revert to reporting only the additional memory that `pcre2_compile()` will
use for the compiled pattern (including any data tables) and make sure
that the limit provided with `pcre2_set_max_pattern_compiled_length()`
also avoid the internal struct overhead.

Fixes: #415
  • Loading branch information
carenas committed Jun 9, 2024
1 parent 6ae58be commit 5790662
Show file tree
Hide file tree
Showing 12 changed files with 546 additions and 1,022 deletions.
8 changes: 4 additions & 4 deletions doc/pcre2_set_max_pattern_compiled_length.3
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH 3 "24 April 2024" "PCRE2 10.44"
.TH PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH 3 "8 Jun 2024" "PCRE2 10.45"
.SH NAME
PCRE2 - Perl-compatible regular expressions (revised API)
.SH SYNOPSIS
Expand All @@ -15,9 +15,9 @@ PCRE2 - Perl-compatible regular expressions (revised API)
.rs
.sp
This function sets, in a compile context, the maximum size (in bytes) for the
memory needed to hold the compiled version of a pattern that is compiled with
this context. The result is always zero. If a pattern that is passed to
\fBpcre2_compile()\fP with this context needs more memory, an error is
memory needed to hold the compiled version of a pattern that is using this
context. The result is always zero. If a pattern that is passed to
\fBpcre2_compile()\fP referencing this context needs more memory, an error is
generated. The default is the largest number that a PCRE2_SIZE variable can
hold, which is effectively unlimited.
.P
Expand Down
4 changes: 2 additions & 2 deletions src/pcre2_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -10608,8 +10608,7 @@ block for storing the compiled pattern and names table. Integer overflow should
no longer be possible because nowadays we limit the maximum value of
cb.names_found and cb.name_entry_size. */

re_blocksize = sizeof(pcre2_real_code) +
CU2BYTES(length +
re_blocksize = CU2BYTES(length +
(PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);

if (re_blocksize > ccontext->max_pattern_compiled_length)
Expand All @@ -10618,6 +10617,7 @@ if (re_blocksize > ccontext->max_pattern_compiled_length)
goto HAD_CB_ERROR;
}

re_blocksize += sizeof(pcre2_real_code);
re = (pcre2_real_code *)
ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
if (re == NULL)
Expand Down
17 changes: 9 additions & 8 deletions src/pcre2test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4397,7 +4397,7 @@ static void
show_memory_info(void)
{
uint32_t name_count, name_entry_size;
PCRE2_SIZE size, cblock_size;
PCRE2_SIZE size, cblock_size, data_size;

/* One of the test_mode values will always be true, but to stop a compiler
warning we must initialize cblock_size. */
Expand All @@ -4417,18 +4417,19 @@ if (test_mode == PCRE32_MODE) cblock_size = sizeof(pcre2_real_code_32);
(void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE);
(void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE);

/* The uint32_t variables are cast before multiplying to stop code analyzers
grumbling about potential overflow. */
/* The uint32_t variables are cast before multiplying to avoid potential
integer overflow. */
data_size = (PCRE2_SIZE)name_count * (PCRE2_SIZE)name_entry_size * (PCRE2_SIZE)code_unit_size;

fprintf(outfile, "Memory allocation - compiled block : %" SIZ_FORM "\n", size);
fprintf(outfile, "Memory allocation - code portion : %" SIZ_FORM "\n", size -
(PCRE2_SIZE)name_count * (PCRE2_SIZE)name_entry_size * (PCRE2_SIZE)code_unit_size -
cblock_size);
fprintf(outfile, "Memory allocation - code size : %" SIZ_FORM "\n", size -
cblock_size - data_size);
if (data_size != 0)
fprintf(outfile, "Memory allocation - data size : %" SIZ_FORM "\n", data_size);

if (pat_patctl.jit != 0)
{
(void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE);
fprintf(outfile, "Memory allocation - JIT code : %" SIZ_FORM "\n", size);
fprintf(outfile, "Memory allocation - JIT code : %" SIZ_FORM "\n", size);
}
}

Expand Down
Loading

0 comments on commit 5790662

Please sign in to comment.