Skip to content
Snippets Groups Projects
Commit 76610c0a authored by Richard van der Hoff's avatar Richard van der Hoff
Browse files

Allocate memory for message blobs on the heap

Messages can be very large, so we don't really want to allocate them on the
stack. Switch to using the heap for them, and try to clean up some of the
string handling while we're at it.
parent f6c05be8
No related branches found
No related tags found
No related merge requests found
......@@ -64,33 +64,49 @@ InboundGroupSession.prototype['create'] = restore_stack(function(session_key) {
InboundGroupSession.prototype['decrypt'] = restore_stack(function(
message
) {
var message_array = array_from_string(message);
var message_buffer = stack(message_array);
var max_plaintext_length = inbound_group_session_method(
Module['_olm_group_decrypt_max_plaintext_length']
)(this.ptr, message_buffer, message_array.length);
// caculating the length destroys the input buffer.
// So we copy the array to a new buffer
var message_buffer = stack(message_array);
var plaintext_buffer = stack(max_plaintext_length + NULL_BYTE_PADDING_LENGTH);
var message_index = stack(4);
var plaintext_length = inbound_group_session_method(Module["_olm_group_decrypt"])(
this.ptr,
message_buffer, message_array.length,
plaintext_buffer, max_plaintext_length,
message_index
);
var message_buffer, plaintext_buffer;
// Pointer_stringify requires a null-terminated argument (the optional
// 'len' argument doesn't work for UTF-8 data).
Module['setValue'](
plaintext_buffer+plaintext_length,
0, "i8"
);
try {
message_buffer = malloc(message.length);
Module['writeAsciiToMemory'](message, message_buffer, true);
var max_plaintext_length = inbound_group_session_method(
Module['_olm_group_decrypt_max_plaintext_length']
)(this.ptr, message_buffer, message.length);
// caculating the length destroys the input buffer, so we need to re-copy it.
Module['writeAsciiToMemory'](message, message_buffer, true);
plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH);
var message_index = stack(4);
return {
"plaintext": Pointer_stringify(plaintext_buffer),
"message_index": Module['getValue'](message_index, "i32")
var plaintext_length = inbound_group_session_method(
Module["_olm_group_decrypt"]
)(
this.ptr,
message_buffer, message.length,
plaintext_buffer, max_plaintext_length,
message_index
);
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
Module['setValue'](
plaintext_buffer+plaintext_length,
0, "i8"
);
return {
"plaintext": UTF8ToString(plaintext_buffer),
"message_index": Module['getValue'](message_index, "i32")
}
} finally {
if (message_buffer !== undefined) {
free(message_buffer);
}
if (plaintext_buffer !== undefined) {
free(plaintext_buffer);
}
}
});
......
......@@ -63,20 +63,36 @@ OutboundGroupSession.prototype['create'] = restore_stack(function() {
);
});
OutboundGroupSession.prototype['encrypt'] = restore_stack(function(plaintext) {
var plaintext_array = array_from_string(plaintext);
var message_length = outbound_group_session_method(
Module['_olm_group_encrypt_message_length']
)(this.ptr, plaintext_array.length);
var plaintext_buffer = stack(plaintext_array);
var message_buffer = stack(message_length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_group_encrypt'])(
this.ptr,
plaintext_buffer, plaintext_array.length,
message_buffer, message_length
);
return Pointer_stringify(message_buffer);
});
OutboundGroupSession.prototype['encrypt'] = function(plaintext) {
var plaintext_buffer, message_buffer;
try {
var plaintext_length = Module['lengthBytesUTF8'](plaintext);
var message_length = outbound_group_session_method(
Module['_olm_group_encrypt_message_length']
)(this.ptr, plaintext_length);
// need to allow space for the terminator (which stringToUTF8 always
// writes), hence + 1.
plaintext_buffer = malloc(plaintext_length + 1);
Module['stringToUTF8'](plaintext, plaintext_buffer, plaintext_length + 1);
message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_group_encrypt'])(
this.ptr,
plaintext_buffer, plaintext_length,
message_buffer, message_length
);
return Module['UTF8ToString'](message_buffer);
} finally {
if (plaintext_buffer !== undefined) {
free(plaintext_buffer);
}
if (message_buffer !== undefined) {
free(message_buffer);
}
}
};
OutboundGroupSession.prototype['session_id'] = restore_stack(function() {
var length = outbound_group_session_method(
......
......@@ -4,9 +4,11 @@ var free = Module['_free'];
var Pointer_stringify = Module['Pointer_stringify'];
var OLM_ERROR = Module['_olm_error']();
/* The 'length' argument to Pointer_stringify doesn't work if the input includes
* characters >= 128; we therefore need to add a NULL character to all of our
* strings. This acts as a symbolic constant to help show what we're doing.
/* The 'length' argument to Pointer_stringify doesn't work if the input
* includes characters >= 128, which makes Pointer_stringify unreliable. We
* could use it on strings which are known to be ascii, but that seems
* dangerous. Instead we add a NULL character to all of our strings and just
* use UTF8ToString.
*/
var NULL_BYTE_PADDING_LENGTH = 1;
......@@ -297,59 +299,90 @@ Session.prototype['matches_inbound_from'] = restore_stack(function(
Session.prototype['encrypt'] = restore_stack(function(
plaintext
) {
var random_length = session_method(
Module['_olm_encrypt_random_length']
)(this.ptr);
var message_type = session_method(
Module['_olm_encrypt_message_type']
)(this.ptr);
var plaintext_array = array_from_string(plaintext);
var message_length = session_method(
Module['_olm_encrypt_message_length']
)(this.ptr, plaintext_array.length);
var random = random_stack(random_length);
var plaintext_buffer = stack(plaintext_array);
var message_buffer = stack(message_length + NULL_BYTE_PADDING_LENGTH);
session_method(Module['_olm_encrypt'])(
this.ptr,
plaintext_buffer, plaintext_array.length,
random, random_length,
message_buffer, message_length
);
return {
"type": message_type,
"body": Pointer_stringify(message_buffer)
};
var plaintext_buffer, message_buffer;
try {
var random_length = session_method(
Module['_olm_encrypt_random_length']
)(this.ptr);
var message_type = session_method(
Module['_olm_encrypt_message_type']
)(this.ptr);
var plaintext_length = Module['lengthBytesUTF8'](plaintext);
var message_length = session_method(
Module['_olm_encrypt_message_length']
)(this.ptr, plaintext_length);
var random = random_stack(random_length);
// need to allow space for the terminator (which stringToUTF8 always
// writes), hence + 1.
plaintext_buffer = malloc(plaintext_length + 1);
Module['stringToUTF8'](plaintext, plaintext_buffer, plaintext_length + 1);
message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH);
session_method(Module['_olm_encrypt'])(
this.ptr,
plaintext_buffer, plaintext_length,
random, random_length,
message_buffer, message_length
);
return {
"type": message_type,
"body": Module['UTF8ToString'](message_buffer),
};
} finally {
if (plaintext_buffer !== undefined) {
free(plaintext_buffer);
}
if (message_buffer !== undefined) {
free(message_buffer);
}
}
});
Session.prototype['decrypt'] = restore_stack(function(
message_type, message
) {
var message_array = array_from_string(message);
var message_buffer = stack(message_array);
var max_plaintext_length = session_method(
Module['_olm_decrypt_max_plaintext_length']
)(this.ptr, message_type, message_buffer, message_array.length);
// caculating the length destroys the input buffer.
// So we copy the array to a new buffer
var message_buffer = stack(message_array);
var plaintext_buffer = stack(
max_plaintext_length + NULL_BYTE_PADDING_LENGTH
);
var plaintext_length = session_method(Module["_olm_decrypt"])(
this.ptr, message_type,
message_buffer, message.length,
plaintext_buffer, max_plaintext_length
);
// Pointer_stringify requires a null-terminated argument (the optional
// 'len' argument doesn't work for UTF-8 data).
Module['setValue'](
plaintext_buffer+plaintext_length,
0, "i8"
);
var message_buffer, plaintext_buffer;
try {
message_buffer = malloc(message.length);
Module['writeAsciiToMemory'](message, message_buffer, true);
var max_plaintext_length = session_method(
Module['_olm_decrypt_max_plaintext_length']
)(this.ptr, message_type, message_buffer, message.length);
// caculating the length destroys the input buffer, so we need to re-copy it.
Module['writeAsciiToMemory'](message, message_buffer, true);
plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH);
var plaintext_length = session_method(Module["_olm_decrypt"])(
this.ptr, message_type,
message_buffer, message.length,
plaintext_buffer, max_plaintext_length
);
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
Module['setValue'](
plaintext_buffer+plaintext_length,
0, "i8"
);
return UTF8ToString(plaintext_buffer);
} finally {
if (message_buffer !== undefined) {
free(message_buffer);
}
if (plaintext_buffer !== undefined) {
free(plaintext_buffer);
}
}
return Pointer_stringify(plaintext_buffer);
});
function Utility() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment