Skip to content

Commit

Permalink
Fix crash with too large clipboard data
Browse files Browse the repository at this point in the history
If too much text is copied in the session, String.fromCharCode.apply()
would crash in Safari on macOS and Chrome on Linux. This commit fixes
this issue by avoiding apply() altogether. Also added test to cover this
issue.
  • Loading branch information
Alex Tanskanen committed Feb 21, 2020
1 parent e4e6a9b commit ceb8ef4
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
6 changes: 5 additions & 1 deletion core/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -1504,7 +1504,11 @@ export default class RFB extends EventTargetMixin {
streamInflator.setInput(null);

if (textData !== null) {
textData = String.fromCharCode.apply(null, textData);
let tmpText = "";
for (let i = 0; i < textData.length; i++) {
tmpText += String.fromCharCode(textData[i]);
}
textData = tmpText;

textData = decodeUTF8(textData);
if ((textData.length > 0) && "\0" === textData.charAt(textData.length - 1)) {
Expand Down
32 changes: 32 additions & 0 deletions tests/test.rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -2514,6 +2514,38 @@ describe('Remote Frame Buffer Protocol Client', function () {
client.removeEventListener("clipboard", spy);
});

it('should be able to handle large Provide messages', function () {
// repeat() is not supported in IE so a loop is needed instead
let expectedData = "hello";
for (let i = 1; i <= 100000; i++) {
expectedData += "hello";
}

let data = [3, 0, 0, 0];
const flags = [0x10, 0x00, 0x00, 0x01];

let text = encodeUTF8(expectedData + "\0");

let deflatedText = deflateWithSize(text);

// How much data we are sending.
push32(data, toUnsigned32bit(-(4 + deflatedText.length)));

data = data.concat(flags);

let sendData = new Uint8Array(data.length + deflatedText.length);
sendData.set(data);
sendData.set(deflatedText, data.length);

const spy = sinon.spy();
client.addEventListener("clipboard", spy);

client._sock._websocket._receive_data(sendData);
expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.text).to.equal(expectedData);
client.removeEventListener("clipboard", spy);
});

});

describe('Handle Notify', function () {
Expand Down

0 comments on commit ceb8ef4

Please sign in to comment.