diff --git a/core/src/socket.rs b/core/src/socket.rs index 8cc82eb71..7520e5270 100644 --- a/core/src/socket.rs +++ b/core/src/socket.rs @@ -321,10 +321,13 @@ impl<'gc> Sockets<'gc> { let xml_socket = XmlSocket::cast(target.into()).expect("target should be XmlSocket"); + // Get XmlSocket read buffer. let mut buffer = xml_socket.read_buffer(); buffer.extend(data); - // Check for a message. + let mut messages = vec![]; + + // Check for messages. while let Some((index, _)) = buffer.iter().enumerate().find(|(_, &b)| b == 0) { @@ -332,8 +335,14 @@ impl<'gc> Sockets<'gc> { // Remove null byte. let _ = buffer.drain(..1); - let message = AvmString::new_utf8_bytes(activation.gc(), &message); + // Store the message in cache. + messages.push(AvmString::new_utf8_bytes(activation.gc(), &message)); + } + // Drop the reference to the buffer, to make sure the SWF can call with close. + drop(buffer); + + for message in messages { let _ = target.call_method( "onData".into(), &[message.into()], diff --git a/tests/tests/swfs/avm1/xml_socket_close_in_handler/output.txt b/tests/tests/swfs/avm1/xml_socket_close_in_handler/output.txt new file mode 100644 index 000000000..a4811a6de --- /dev/null +++ b/tests/tests/swfs/avm1/xml_socket_close_in_handler/output.txt @@ -0,0 +1,6 @@ +connected +true +data: +Hello! +Closing socket in onData handler +Successfully closed socket diff --git a/tests/tests/swfs/avm1/xml_socket_close_in_handler/socket.json b/tests/tests/swfs/avm1/xml_socket_close_in_handler/socket.json new file mode 100644 index 000000000..c493046e4 --- /dev/null +++ b/tests/tests/swfs/avm1/xml_socket_close_in_handler/socket.json @@ -0,0 +1,13 @@ +[ + { + "type": "Send", + "payload": [ 72, 101, 108, 108, 111, 33, 0 ] + }, + { + "type": "Send", + "payload": [ 60, 114, 111, 111, 116, 62, 60, 105, 116, 101, 109, 32, 47, 62, 60, 47, 114, 111, 111, 116, 62, 0 ] + }, + { + "type": "WaitForDisconnect" + } +] diff --git a/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.as b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.as new file mode 100644 index 000000000..d20a645af --- /dev/null +++ b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.as @@ -0,0 +1,23 @@ +class Test { + static function main() { + var socket = new XMLSocket(); + + socket.onConnect = function (status:Boolean) { + trace("connected"); + trace(status); + }; + + socket.onData = function (data:String) { + trace("data:") + trace(data); + trace("Closing socket in onData handler"); + socket.close(); + trace("Successfully closed socket"); + }; + socket.onClose = function () { + trace("closed"); + }; + + socket.connect("localhost", 8001); + } +} diff --git a/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.swf b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.swf new file mode 100644 index 000000000..3799ad477 Binary files /dev/null and b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.swf differ diff --git a/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.toml b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.toml new file mode 100644 index 000000000..0d5c2c67f --- /dev/null +++ b/tests/tests/swfs/avm1/xml_socket_close_in_handler/test.toml @@ -0,0 +1 @@ +num_ticks = 10