diff options
author | Pierre Ossman <ossman@cendio.se> | 2022-10-27 16:19:58 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2022-10-27 16:24:27 +0200 |
commit | 6eb17b27a0c86cc12321d7279eef45713b37aa2f (patch) | |
tree | 87c1da2d16eef1d5ea25668f8efc07af28c3ac1a | |
parent | 6b555f1f746781e05348cdc9f1c7901dacc0114a (diff) | |
download | novnc-6eb17b27a0c86cc12321d7279eef45713b37aa2f.tar.gz |
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.
-rw-r--r-- | core/rfb.js | 19 | ||||
-rw-r--r-- | tests/test.rfb.js | 8 |
2 files changed, 23 insertions, 4 deletions
diff --git a/core/rfb.js b/core/rfb.js index 707de0f..c96518d 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 eb70386..ad00edf 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]; |