diff options
author | Björn-Egil Dahlberg <[email protected]> | 2014-01-07 18:40:43 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2014-01-07 18:40:43 +0100 |
commit | 71e6fe5bcbd7b2b98dfa159db34ee1fe14823a56 (patch) | |
tree | 671f156892b7d2c36a005e90796267738630b1d9 /erts/emulator | |
parent | 006df089ffd6c024a4f5099d27ebcda5a684f0ef (diff) | |
download | otp-71e6fe5bcbd7b2b98dfa159db34ee1fe14823a56.tar.gz otp-71e6fe5bcbd7b2b98dfa159db34ee1fe14823a56.tar.bz2 otp-71e6fe5bcbd7b2b98dfa159db34ee1fe14823a56.zip |
erts: Fix bs_get_integer instruction
The instruction bs_get_integer could unnecessarily trigger a garbage collection
in failure cases which is unwanted or outright dangerous.
Ex:
<<X:Sz,_/bits>> = <<"some binary">>
Previously, if Sz induced X to a bignum it would reserved memory size this on
the heap via a garbage collection before checking if the size could actually match.
It will now check the binary size before triggering a collection.
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 78ab6fa30f..592cfe273f 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -4326,7 +4326,19 @@ void process_main(void) flags = Arg(2); BsGetFieldSize(tmp_arg2, (flags >> 3), ClauseFail(), size); if (size >= SMALL_BITS) { - Uint wordsneeded = 1+WSIZE(NBYTES((Uint) size)); + Uint wordsneeded; + /* check bits size before potential gc. + * We do not want a gc and then realize we don't need + * the allocated space (i.e. if the op fails) + * + * remember to reacquire the matchbuffer after gc. + */ + + mb = ms_matchbuffer(tmp_arg1); + if (mb->size - mb->offset < size) { + ClauseFail(); + } + wordsneeded = 1+WSIZE(NBYTES((Uint) size)); TestHeapPreserve(wordsneeded, Arg(1), tmp_arg1); } mb = ms_matchbuffer(tmp_arg1); |