mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/spirv: Do not sign-extend *ptr in vkd3d_spirv_build_string().
"char" is (potentially) signed, so casting it to uint32_t will sign-extend it. Because we use |= to assign it to "word", and don't otherwise mask out the higher bits either, we effectively set subsequent bytes in the same word to 0xff for input bytes > 0x7f. That potentially includes the \0 terminator. For example, "é" (U+00e9) is "\xc3\xa9" when encoded as UTF-8, and would get us 0xffffffc3 instead of 0x0000a9c3.
This commit is contained in:
Notes:
Henri Verbeet
2025-03-05 14:16:35 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1400
@@ -829,16 +829,16 @@ static unsigned int vkd3d_spirv_string_word_count(const char *str)
|
||||
static void vkd3d_spirv_build_string(struct vkd3d_spirv_stream *stream,
|
||||
const char *str, unsigned int word_count)
|
||||
{
|
||||
unsigned int word_idx, i;
|
||||
const char *ptr = str;
|
||||
uint32_t *ptr;
|
||||
|
||||
for (word_idx = 0; word_idx < word_count; ++word_idx)
|
||||
{
|
||||
uint32_t word = 0;
|
||||
for (i = 0; i < sizeof(uint32_t) && *ptr; ++i)
|
||||
word |= (uint32_t)*ptr++ << (8 * i);
|
||||
vkd3d_spirv_build_word(stream, word);
|
||||
}
|
||||
if (!vkd3d_array_reserve((void **)&stream->words, &stream->capacity,
|
||||
stream->word_count + word_count, sizeof(*stream->words)))
|
||||
return;
|
||||
|
||||
ptr = &stream->words[stream->word_count];
|
||||
ptr[word_count - 1] = 0;
|
||||
memcpy(ptr, str, strlen(str));
|
||||
stream->word_count += word_count;
|
||||
}
|
||||
|
||||
typedef uint32_t (*vkd3d_spirv_build_pfn)(struct vkd3d_spirv_builder *builder);
|
||||
|
Reference in New Issue
Block a user