The test has been historcially flaky, and it turns out to be real crashes. The data length (which is in bytes) shouldn't be used, since the unsigned short buffer is counted in words (== sizeof(unsigned short)). Therefore the code as it stood actually caused buffer overrun.
In addition, the code happened to work because NSUTF16StringEncoding happened to give us little-endian UTF-16 strings on little-endian platforms (and it actually returns a UTF-16 string with the UTF-16LE marker FF FE as its first "charcarter").
All this means that if a string does not contain any surrogate pairs and has a length of 5, the actually (supposedly immutable) NSData length is 12 (= 2 bytes BOM + 2 * 5 for 5 such UTF-16 characters), and the unsigned short buffer is only valid between buf[0] and buf[5] inclusive.
This PR reverts to how OpenVanilla used to call VXHanConvert functions in an endian- and memory-safe manner.
The test has been historcially flaky, and it turns out to be real crashes. The data length (which is in bytes) shouldn't be used, since the
unsigned short
buffer is counted in words (== sizeof(unsigned short)). Therefore the code as it stood actually caused buffer overrun.In addition, the code happened to work because
NSUTF16StringEncoding
happened to give us little-endian UTF-16 strings on little-endian platforms (and it actually returns a UTF-16 string with the UTF-16LE marker FF FE as its first "charcarter").All this means that if a string does not contain any surrogate pairs and has a length of 5, the actually (supposedly immutable) NSData length is 12 (= 2 bytes BOM + 2 * 5 for 5 such UTF-16 characters), and the unsigned short buffer is only valid between buf[0] and buf[5] inclusive.
This PR reverts to how OpenVanilla used to call VXHanConvert functions in an endian- and memory-safe manner.