aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_io_queue.c
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2017-09-20 19:55:22 +0200
committerJohn Högberg <[email protected]>2017-09-22 14:53:14 +0200
commitae559453fed714fecd4284c7a4332bc2c8483c29 (patch)
tree0673aff5fa2d3084831955aa9be002b760d0ab62 /erts/emulator/beam/erl_io_queue.c
parent0f4d186e1b2213e533975db393a8c87e1303fddd (diff)
downloadotp-ae559453fed714fecd4284c7a4332bc2c8483c29.tar.gz
otp-ae559453fed714fecd4284c7a4332bc2c8483c29.tar.bz2
otp-ae559453fed714fecd4284c7a4332bc2c8483c29.zip
Correctly append sub-binaries in iolist_to_iovec
The byte_offset of sub-binaries wasn't taken into account for ProcBins, subtly ruining the results. The test suite didn't catch it since it didn't check for sub-binaries in particular, and only checked for equality between variations -- not whether the output was equal to the input.
Diffstat (limited to 'erts/emulator/beam/erl_io_queue.c')
-rw-r--r--erts/emulator/beam/erl_io_queue.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/erts/emulator/beam/erl_io_queue.c b/erts/emulator/beam/erl_io_queue.c
index a01b676d39..190ba6bbb9 100644
--- a/erts/emulator/beam/erl_io_queue.c
+++ b/erts/emulator/beam/erl_io_queue.c
@@ -973,9 +973,10 @@ static int iol2v_append_binary(iol2v_state_t *state, Eterm bin_term) {
UWord binary_size;
Uint byte_offset, bit_offset, bit_size;
+ byte *binary_data;
+
Eterm *parent_header;
Eterm parent_binary;
- byte *binary_data;
ASSERT(state->bytereds_available > state->bytereds_spent);
@@ -1001,14 +1002,14 @@ static int iol2v_append_binary(iol2v_state_t *state, Eterm bin_term) {
erts_emasculate_writable_binary(pb);
}
- binary_data = pb->bytes;
+ binary_data = &((byte*)pb->bytes)[byte_offset];
} else {
ErlHeapBin *hb = (ErlHeapBin*)parent_header;
ASSERT(thing_subtag(*parent_header) == HEAP_BINARY_SUBTAG);
ASSERT(is_bin_small);
- binary_data = &((unsigned char*)&hb->data)[byte_offset];
+ binary_data = &((byte*)&hb->data)[byte_offset];
}
if (!is_bin_small && (state->acc_size == 0 || !is_acc_small)) {