diff options
author | David Mitchell <davem@iabyn.com> | 2016-10-30 12:15:03 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-01-24 12:09:24 +0000 |
commit | 1acab4c5e64e8d27d6452f7758b159adf276d017 (patch) | |
tree | 9cccbd251fc88ed45dc8da01c67ba42348864e0c /regexp.h | |
parent | 64afbd292eada08042044fb6bc5a8dabf803ec53 (diff) | |
download | perl-1acab4c5e64e8d27d6452f7758b159adf276d017.tar.gz |
better handle freeing of code blocks in /(?{...})/
[perl #129140] attempting double-free
Thus fixes some leaks and double frees in regexes which contain code
blocks.
During compilation, an array of struct reg_code_block's is malloced.
Initially this is just attached to the RExC_state_t struct local var in
Perl_re_op_compile(). Later it may be attached to a pattern. The difficulty
is ensuring that the array is free()d (and the ref counts contained within
decremented) should compilation croak early, while avoiding double frees
once the array has been attached to a regex.
The current mechanism of making the array the PVX of an SV is a bit flaky,
as the array can be realloced(), and code can be re-entered when utf8 is
detected mid-compilation.
This commit changes the array into separately malloced head and body.
The body contains the actual array, and can be realloced. The head
contains a pointer to the array, plus size and an 'attached' boolean.
This indicates whether the struct has been attached to a regex, and is
effectively a 1-bit ref count.
Whenever a head is allocated, SAVEDESTRUCTOR_X() is used to call
S_free_codeblocks() to free the head and body on scope exit. This function
skips the freeing if 'attached' is true, and this flag is set only at the
point where the head gets attached to the regex.
In one way this complicates the code, since the num_code_blocks field is now
not always available (it's only there is a head has been allocated), but
mainly its simplifies, since all the book-keeping is now done in the two
new static functions S_alloc_code_blocks() and S_free_codeblocks()
Diffstat (limited to 'regexp.h')
-rw-r--r-- | regexp.h | 8 |
1 files changed, 8 insertions, 0 deletions
@@ -85,6 +85,14 @@ struct reg_code_block { REGEXP *src_regex; }; +/* array of reg_code_block's plus header info */ + +struct reg_code_blocks { + bool attached; /* we're attached to a regex (don't need freeing) */ + int count; /* how many code blocks */ + struct reg_code_block *cb; /* array of reg_code_block's */ +}; + /* The regexp/REGEXP struct, see L<perlreapi> for further documentation |