From fee115b13f17315ad4a66e098fa62631f5970639 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 27 Oct 2022 15:59:48 +0200 Subject: [PATCH 1/5] Update method to limit assertion output Newer versions of the test framework use the inspect() method instead of toString() for overriding the default output. --- tests/test.rfb.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 75d1e118..edb98cb4 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -111,11 +111,11 @@ describe('Remote Frame Buffer Protocol Client', function () { }; // Avoiding printing the entire Websock buffer on errors - Websock.prototype.toString = function () { return "[object Websock]"; }; + Websock.prototype.inspect = function () { return "[object Websock]"; }; }); after(function () { - delete Websock.prototype.toString; + delete Websock.prototype.inspect; this.clock.restore(); window.requestAnimationFrame = raf; window.ResizeObserver = realObserver; From 337fb06535a8a89e11dee1c52b66c4e5398d5cfa Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 27 Oct 2022 16:02:02 +0200 Subject: [PATCH 2/5] Restore Websock.allocateBuffers() after tests This was accidentally removed in 0a6aec3578. --- tests/test.rfb.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test.rfb.js b/tests/test.rfb.js index edb98cb4..432bcba9 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -115,6 +115,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); after(function () { + Websock.prototype._allocateBuffers = Websock.prototype._oldAllocateBuffers; delete Websock.prototype.inspect; this.clock.restore(); window.requestAnimationFrame = raf; From 0410cbc1908c460eb2d339e2d1a703ba1d07815d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 27 Oct 2022 16:02:38 +0200 Subject: [PATCH 3/5] Remove redundant inspect() override We do this for all RFB tests now, not just these specific assertions. --- tests/assertions.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/assertions.js b/tests/assertions.js index c33c81ec..739f6375 100644 --- a/tests/assertions.js +++ b/tests/assertions.js @@ -29,12 +29,6 @@ chai.use(function (_chai, utils) { _chai.Assertion.addMethod('sent', function (targetData) { const obj = this._obj; - obj.inspect = () => { - const res = { _websocket: obj._websocket, rQi: obj._rQi, _rQ: new Uint8Array(obj._rQ.buffer, 0, obj._rQlen), - _sQ: new Uint8Array(obj._sQ.buffer, 0, obj._sQlen) }; - res.prototype = obj; - return res; - }; const data = obj._websocket._getSentData(); let same = true; if (data.length != targetData.length) { From 6b555f1f746781e05348cdc9f1c7901dacc0114a Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 27 Oct 2022 16:03:22 +0200 Subject: [PATCH 4/5] Mask unsupported clipboard characters Add a more explicit '?' for characters that the clipboard cannot handle, instead of getting random junk. --- core/rfb.js | 10 ++++++++-- tests/test.rfb.js | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/rfb.js b/core/rfb.js index e6647eff..707de0ff 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -492,8 +492,14 @@ export default class RFB extends EventTargetMixin { } else { let data = new Uint8Array(text.length); for (let i = 0; i < text.length; i++) { - // FIXME: text can have values outside of Latin1/Uint8 - data[i] = text.charCodeAt(i); + let code = text.charCodeAt(i); + + /* Only ISO 8859-1 is supported */ + if (code > 0xff) { + code = 0x3f; // '?' + } + + data[i] = code; } RFB.messages.clientCutText(this._sock, data); diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 432bcba9..eb703860 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -433,6 +433,14 @@ describe('Remote Frame Buffer Protocol Client', function () { new Uint8Array([97, 98, 99])); }); + it('should mask unsupported characters', function () { + client.clipboardPasteFrom('abc€'); + + expect(RFB.messages.clientCutText).to.have.been.calledOnce; + expect(RFB.messages.clientCutText).to.have.been.calledWith(client._sock, + new Uint8Array([97, 98, 99, 63])); + }); + it('should send an notify if extended clipboard is supported by server', function () { // Send our capabilities let data = [3, 0, 0, 0]; From 6eb17b27a0c86cc12321d7279eef45713b37aa2f Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 27 Oct 2022 16:19:58 +0200 Subject: [PATCH 5/5] Correctly mask non-BMP clipboard characters JavaScript strings use UTF-16 encoding under the hood, but we only want a single '?' per character we replace. So we need to be more careful which methods we use when iterating over the clipboard string. --- core/rfb.js | 19 +++++++++++++++---- tests/test.rfb.js | 8 ++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/core/rfb.js b/core/rfb.js index 707de0ff..c96518d8 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -490,16 +490,27 @@ export default class RFB extends EventTargetMixin { this._clipboardText = text; RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]); } else { - let data = new Uint8Array(text.length); - for (let i = 0; i < text.length; i++) { - let code = text.charCodeAt(i); + let length, i; + let data; + + length = 0; + // eslint-disable-next-line no-unused-vars + for (let codePoint of text) { + length++; + } + + data = new Uint8Array(length); + + i = 0; + for (let codePoint of text) { + let code = codePoint.codePointAt(0); /* Only ISO 8859-1 is supported */ if (code > 0xff) { code = 0x3f; // '?' } - data[i] = code; + data[i++] = code; } RFB.messages.clientCutText(this._sock, data); diff --git a/tests/test.rfb.js b/tests/test.rfb.js index eb703860..ad00edfb 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -441,6 +441,14 @@ describe('Remote Frame Buffer Protocol Client', function () { new Uint8Array([97, 98, 99, 63])); }); + it('should mask characters, not UTF-16 code points', function () { + client.clipboardPasteFrom('😂'); + + expect(RFB.messages.clientCutText).to.have.been.calledOnce; + expect(RFB.messages.clientCutText).to.have.been.calledWith(client._sock, + new Uint8Array([63])); + }); + it('should send an notify if extended clipboard is supported by server', function () { // Send our capabilities let data = [3, 0, 0, 0];