mirror of https://github.com/bjornbytes/lovr.git
Fix sending strings with \0 through channels
A null-char is valid part of Lua string. When such a string is sent through the channel, its length should be stored as well to be able to correctly reconstruct it on the other thread. The bug was triggered with this code: s1 = 'a \0 b' print(#s1) -- 5 ch:push(s1) s2 = ch:pop() print(#s2) -- 2
This commit is contained in:
parent
72334cc1f2
commit
da9328e72c
|
@ -46,10 +46,11 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) {
|
|||
variant->type = TYPE_STRING;
|
||||
size_t length;
|
||||
const char* string = lua_tolstring(L, index, &length);
|
||||
variant->value.string = malloc(length + 1);
|
||||
lovrAssert(variant->value.string, "Out of memory");
|
||||
memcpy(variant->value.string, string, length);
|
||||
variant->value.string[length] = '\0';
|
||||
variant->value.string.pointer = malloc(length + 1);
|
||||
lovrAssert(variant->value.string.pointer, "Out of memory");
|
||||
memcpy(variant->value.string.pointer, string, length);
|
||||
variant->value.string.pointer[length] = '\0';
|
||||
variant->value.string.length = length;
|
||||
break;
|
||||
|
||||
case LUA_TUSERDATA:
|
||||
|
@ -80,7 +81,7 @@ int luax_pushvariant(lua_State* L, Variant* variant) {
|
|||
case TYPE_NIL: lua_pushnil(L); return 1;
|
||||
case TYPE_BOOLEAN: lua_pushboolean(L, variant->value.boolean); return 1;
|
||||
case TYPE_NUMBER: lua_pushnumber(L, variant->value.number); return 1;
|
||||
case TYPE_STRING: lua_pushstring(L, variant->value.string); return 1;
|
||||
case TYPE_STRING: lua_pushlstring(L, variant->value.string.pointer, variant->value.string.length); return 1;
|
||||
case TYPE_OBJECT: _luax_pushtype(L, variant->value.object.type, hash64(variant->value.object.type, strlen(variant->value.object.type)), variant->value.object.pointer); return 1;
|
||||
default: return 0;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ static struct {
|
|||
|
||||
void lovrVariantDestroy(Variant* variant) {
|
||||
switch (variant->type) {
|
||||
case TYPE_STRING: free(variant->value.string); return;
|
||||
case TYPE_STRING: free(variant->value.string.pointer); return;
|
||||
case TYPE_OBJECT: lovrRelease(variant->value.object.pointer, variant->value.object.destructor); return;
|
||||
default: return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -33,7 +34,10 @@ typedef enum {
|
|||
typedef union {
|
||||
bool boolean;
|
||||
double number;
|
||||
char* string;
|
||||
struct {
|
||||
char* pointer;
|
||||
size_t length;
|
||||
} string;
|
||||
struct {
|
||||
void* pointer;
|
||||
const char* type;
|
||||
|
|
Loading…
Reference in New Issue