-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Description
When poking a string into buffer using buffer_poke, it can miss some bytes. This happens whenever string should contain UTF-8 charactes longer than 1 byte, such as "¤" or other non-ASCII characters.
The problem arises that JavaScript uses UTF-16 characters instead, and buffer_poke uses this string directly for reading its length and bytes. It should instead convert UTF-16 string into UTF-8, or something, so getting bytes is done properly.
This problem is not appearent in buffer_write, as it handles string conversion into UTF8 correctly. Compare the implementation of these both here:
buffer_write:
https://github.com/YoYoGames/GameMaker-HTML5/blob/8f87db22cefd0cb1d9e706523730946e1319a117/scripts/yyBuffer.js#L1309
Here are direct code snippets from both.
First buffer_poke, note that .charCodeAtis done directly at the _value which is function argument.
case eBuffer_String:
case eBuffer_Text:
{
for (var i = 0; i < _value.length; i++) {
var charCode = _value.charCodeAt(i) & 0xff; // Now UTF8, so only a byte in size
this.m_DataView.setUint8(_offset++, charCode, true);
}
// "text" mode doesn't add a NULL at the end.
if (_type === eBuffer_String) {
this.m_DataView.setUint8(_offset++, 0, true);
}
this.yyb_UpdateUsedSize(_offset);
}
return;On other hand, implementation of buffer_writepreprocesses the string into UTF8 as seen here:
case eBuffer_String:
case eBuffer_Text:
{
for (var i = 0; i < UTF8_String.length; i++) {
var charCode = UTF8_String.charCodeAt(i) & 0xff; // Now UTF8, so only a byte in size
this.m_DataView.setUint8(this.m_BufferIndex++, charCode, true);
}
// "text" mode doesn't add a NULL at the end.
if (_type === eBuffer_String) {
this.m_DataView.setUint8(this.m_BufferIndex++, 0, true);
}
}
break;The conversion is done earlier with this piece of code:
var sizeneeded = BufferSizeOf(_type);
if( ( _type === eBuffer_String ) || ( _type === eBuffer_Text ) ){
UTF8_String = UnicodeToUTF8(_value);
sizeneeded = UTF8_String.length;
if( _type === eBuffer_String ) sizeneeded++; // null at the end of a string (not text)
}The buffer poke doesn't do this.
Steps To Reproduce
- Run example project in Windows
- Compare console output -> Should all be the same.
- Run example project in HTML5 export
- Compare console output -> buffer_poke differs (misses bytes)
Which version of GameMaker are you reporting this issue for?
IDE v2024.1400.4.1023 Runtime v2024.1400.4.998
Which operating system(s) are you seeing the problem on?
Windows 10.0.19045.0
Metadata
Metadata
Assignees
Labels
Type
Projects
Status