mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-2043: Fix playback of recordings which have multibyte character instructions.
This commit is contained in:
@@ -334,9 +334,51 @@ Guacamole.SessionRecording = function SessionRecording(source, refreshInterval)
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the size in bytes of the given UTF8 string.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {!string} str
|
||||||
|
* The string to calculate the size in bytes.
|
||||||
|
*
|
||||||
|
* @returns {!number}
|
||||||
|
* The size in bytes of the given string.
|
||||||
|
*/
|
||||||
|
var getUtf8StringByteSize = function(str) {
|
||||||
|
|
||||||
|
var byteSize = str.length;
|
||||||
|
for (var i = str.length - 1; i >= 0; i--) {
|
||||||
|
var code = str.charCodeAt(i);
|
||||||
|
// A UTF8 character with such a code will be stored
|
||||||
|
// using two bytes. So we add one byte to the
|
||||||
|
// original string length to get the byte size.
|
||||||
|
if (code > 0x7F && code <= 0x7FF)
|
||||||
|
byteSize++;
|
||||||
|
// This is either a 3 byte UTF8 character or a low
|
||||||
|
// surrogate of a character which JavaSript
|
||||||
|
// interprets as two separate codes. More details:
|
||||||
|
// https://mathiasbynens.be/notes/javascript-encoding
|
||||||
|
else if (code > 0x7FF && code <= 0xFFFF)
|
||||||
|
byteSize += 2;
|
||||||
|
// If this is the low (trail) surrogate, we must skip
|
||||||
|
// the high surrogate code (i - 1). We already have
|
||||||
|
// the original length for two separate codes (this is
|
||||||
|
// how JavaScript interprets the character) plus
|
||||||
|
// we added two bytes at the previous step.
|
||||||
|
// Overall, 4 bytes for the character.
|
||||||
|
if (code >= 0xDC00 && code <= 0xDFFF)
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
return byteSize;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the size of the given Guacamole instruction element, in
|
* Calculates the size of the given Guacamole instruction element, in
|
||||||
* Unicode characters. The size returned includes the characters which
|
* bytes. This is necessary because the recording is stored as a Blob
|
||||||
|
* and we need to know the start and end positions of a frame (i.e.
|
||||||
|
* all the instructions which make up the frame).
|
||||||
|
* The size returned includes the characters which
|
||||||
* make up the length, the "." separator between the length and the
|
* make up the length, the "." separator between the length and the
|
||||||
* element itself, and the "," or ";" terminator which follows the
|
* element itself, and the "," or ";" terminator which follows the
|
||||||
* element.
|
* element.
|
||||||
@@ -347,25 +389,26 @@ Guacamole.SessionRecording = function SessionRecording(source, refreshInterval)
|
|||||||
* the initial length, "." separator, and "," or ";" terminator).
|
* the initial length, "." separator, and "," or ";" terminator).
|
||||||
*
|
*
|
||||||
* @returns {!number}
|
* @returns {!number}
|
||||||
* The number of Unicode characters which would make up the given
|
* The number of bytes which would make up the given
|
||||||
* element within a Guacamole instruction.
|
* element within a Guacamole instruction to be stored in Blob.
|
||||||
*/
|
*/
|
||||||
var getElementSize = function getElementSize(value) {
|
var getElementSize = function getElementSize(value) {
|
||||||
|
|
||||||
var valueLength = value.length;
|
|
||||||
|
|
||||||
// Calculate base size, assuming at least one digit, the "."
|
// Calculate base size, assuming at least one digit, the "."
|
||||||
// separator, and the "," or ";" terminator
|
// separator, and the "," or ";" terminator
|
||||||
var protocolSize = valueLength + 3;
|
var byteSize = getUtf8StringByteSize(value) + 3;
|
||||||
|
|
||||||
|
// We need this to calculate the size of the length substring.
|
||||||
|
var valueLength = Guacamole.Parser.codePointCount(value);
|
||||||
|
|
||||||
// Add one character for each additional digit that would occur
|
// Add one character for each additional digit that would occur
|
||||||
// in the element length prefix
|
// in the element length prefix
|
||||||
while (valueLength >= 10) {
|
while (valueLength >= 10) {
|
||||||
protocolSize++;
|
byteSize++;
|
||||||
valueLength = Math.floor(valueLength / 10);
|
valueLength = Math.floor(valueLength / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
return protocolSize;
|
return byteSize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user