aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2014-01-07 18:40:43 +0100
committerBjörn-Egil Dahlberg <[email protected]>2014-01-07 18:40:43 +0100
commit71e6fe5bcbd7b2b98dfa159db34ee1fe14823a56 (patch)
tree671f156892b7d2c36a005e90796267738630b1d9 /erts
parent006df089ffd6c024a4f5099d27ebcda5a684f0ef (diff)
downloadotp-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')
-rw-r--r--erts/emulator/beam/beam_emu.c14
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);