Commit ac5f8e36 authored by Hanspeter Portner's avatar Hanspeter Portner

various fixes.

* properly check for moony->chunk buffer overflows
* change order of obj:foreach return values
* fixes reported by scan-build
* fixes reported by valgrind
parent 416b74b1
Pipeline #4259372 passed with stages
in 16 minutes and 59 seconds
......@@ -143,7 +143,7 @@ static const luaL_Reg lunmap_mt [] = {
static int
_lhash_map__index(lua_State *L)
{
moony_t *moony = lua_touserdata(L, lua_upvalueindex(1));
//moony_t *moony = lua_touserdata(L, lua_upvalueindex(1));
if(lua_isstring(L, 2))
{
......@@ -338,8 +338,12 @@ _log(lua_State *L)
if(end)
{
if(end != moony->trace)
{
*end++ = '\n'; // append to
snprintf(end, MOONY_MAX_ERROR_LEN - (end - moony->trace), "%s", res);
*end = '\0';
}
const size_t remaining = MOONY_MAX_ERROR_LEN - (end - moony->trace);
snprintf(end, MOONY_MAX_ERROR_LEN - remaining, "%s", res);
moony->trace_out = 1; // set flag
}
......@@ -603,10 +607,10 @@ _state_save(LV2_Handle instance, LV2_State_Store_Function store,
strlen(chunk) + 1,
moony->forge.String,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
(void)status; //TODO check status
free(chunk);
}
//TODO check status
const int32_t minor_version = MOONY_MINOR_VERSION;
status = store(
......@@ -616,7 +620,7 @@ _state_save(LV2_Handle instance, LV2_State_Store_Function store,
sizeof(int32_t),
moony->forge.Int,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
//TODO check status
(void)status; //TODO check status
const int32_t micro_version = MOONY_MICRO_VERSION;
status = store(
......@@ -626,7 +630,7 @@ _state_save(LV2_Handle instance, LV2_State_Store_Function store,
sizeof(int32_t),
moony->forge.Int,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
//TODO check status
(void)status; //TODO check status
atom_ser_t ser = {
.moony = NULL,
......@@ -723,7 +727,7 @@ _state_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_St
if(!micro_version || (size != sizeof(int32_t)) || (type != moony->forge.Int) )
micro_version = NULL;
//TODO check preset verstion with current plugin version for API compatibility
//TODO check preset version with current plugin version for API compatibility
// get code chunk
const char *chunk = retrieve(
......@@ -733,7 +737,7 @@ _state_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_St
&type,
&flags2);
if(chunk && size && (type == moony->forge.String) )
if(chunk && (size <= MOONY_MAX_CHUNK_LEN) && (type == moony->forge.String) )
{
strncpy(moony->chunk, chunk, size);
......@@ -745,6 +749,10 @@ _state_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_St
moony->dirty_out = 1; // trigger update of UI
moony->props_out = 1; // trigger update of UI
}
else
{
moony_err(moony, "chunk too long");
}
const uint8_t *body = retrieve(
state,
......@@ -1052,7 +1060,7 @@ moony_init(moony_t *moony, const char *subject, double sample_rate,
latom_driver_hash[pos].type = moony->forge.Sequence;
latom_driver_hash[pos++].driver = &latom_sequence_driver;
assert(pos++ == DRIVER_HASH_MAX);
assert(pos == DRIVER_HASH_MAX);
qsort(latom_driver_hash, DRIVER_HASH_MAX, sizeof(latom_driver_hash_t), _hash_sort);
if(opts)
......@@ -1661,7 +1669,8 @@ moony_in(moony_t *moony, const LV2_Atom_Sequence *control, LV2_Atom_Sequence *no
int32_t sequence_num = 0;
if(sequence && (sequence->atom.type == moony->forge.Int))
sequence_num = sequence->body; //FIXME use
sequence_num = sequence->body;
(void)sequence_num; //FIXME use
if( subject
&& (subject->atom.type == moony->forge.URID)
......@@ -1703,7 +1712,8 @@ moony_in(moony_t *moony, const LV2_Atom_Sequence *control, LV2_Atom_Sequence *no
int32_t sequence_num = 0;
if(sequence && (sequence->atom.type == moony->forge.Int))
sequence_num = sequence->body; //FIXME use
sequence_num = sequence->body;
(void)sequence_num; //FIXME use
if( subject
&& (subject->atom.type == moony->forge.URID)
......@@ -1726,27 +1736,34 @@ moony_in(moony_t *moony, const LV2_Atom_Sequence *control, LV2_Atom_Sequence *no
// load chunk
const char *str = LV2_ATOM_BODY_CONST(value);
if(luaL_dostring(L, str)) // failed loading chunk
if(value->size <= MOONY_MAX_CHUNK_LEN)
{
moony_error(moony);
}
else // succeeded loading chunk
{
strncpy(moony->chunk, str, value->size);
moony->error[0] = 0x0; // reset error flag
if(moony->state_atom)
if(luaL_dostring(L, str)) // failed loading chunk
{
moony_error(moony);
}
else // succeeded loading chunk
{
// restore Lua defined properties
lua_rawgeti(L, LUA_REGISTRYINDEX, UDATA_OFFSET + MOONY_UDATA_COUNT + MOONY_CCLOSURE_RESTORE);
if(lua_pcall(L, 0, 0, 0))
moony_error(moony);
strncpy(moony->chunk, str, value->size);
moony->error[0] = 0x0; // reset error flag
if(moony->state_atom)
{
// restore Lua defined properties
lua_rawgeti(L, LUA_REGISTRYINDEX, UDATA_OFFSET + MOONY_UDATA_COUNT + MOONY_CCLOSURE_RESTORE);
if(lua_pcall(L, 0, 0, 0))
moony_error(moony);
#ifdef USE_MANUAL_GC
lua_gc(L, LUA_GCSTEP, 0);
lua_gc(L, LUA_GCSTEP, 0);
#endif
}
}
once = true;
once = true;
}
}
else
{
moony_err(moony, "chunk too long");
}
// apply stash
......
......@@ -318,9 +318,8 @@ const latom_driver_t latom_string_driver = {
// Literal driver
static int
_latom_literal__indexk(lua_State *L, latom_t *latom)
_latom_literal__indexk(lua_State *L, latom_t *latom, const char *key)
{
const char *key = lua_tostring(L, 2);
if(!strcmp(key, "datatype"))
lua_pushinteger(L, latom->body.lit->datatype);
else if(!strcmp(key, "lang"))
......@@ -506,9 +505,8 @@ _latom_obj__indexi(lua_State *L, latom_t *latom)
}
static int
_latom_obj__indexk(lua_State *L, latom_t *latom)
_latom_obj__indexk(lua_State *L, latom_t *latom, const char *key)
{
const char *key = lua_tostring(L, 2);
if(!strcmp(key, "id"))
lua_pushinteger(L, latom->body.obj->id);
else if(!strcmp(key, "otype"))
......@@ -543,14 +541,17 @@ _latom_obj_foreach_itr(lua_State *L)
if(!lv2_atom_object_is_end(latom->body.obj, latom->atom->size, latom->iter.obj.prop))
{
// push key/context
// push key
lua_pushinteger(L, latom->iter.obj.prop->key);
lua_pushinteger(L, latom->iter.obj.prop->context);
// push atom
lua_pushvalue(L, lua_upvalueindex(2));
latom_t *litem = lua_touserdata(L, lua_upvalueindex(2));
litem->atom = &latom->iter.obj.prop->value;
litem->body.raw = LV2_ATOM_BODY_CONST(litem->atom);
// push context
lua_pushinteger(L, latom->iter.obj.prop->context);
// advance iterator
latom->iter.obj.prop = lv2_atom_object_next(latom->iter.obj.prop);
......@@ -587,13 +588,10 @@ const latom_driver_t latom_object_driver = {
};
static int
_latom_seq__indexk(lua_State *L, latom_t *latom)
_latom_seq__indexk(lua_State *L, latom_t *latom, const char *key)
{
const char *key = lua_tostring(L, 2);
if(!strcmp(key, "unit"))
lua_pushinteger(L, latom->body.seq->unit);
else if(!strcmp(key, "pad"))
lua_pushinteger(L, latom->body.seq->pad);
else
lua_pushnil(L);
return 1;
......@@ -805,9 +803,8 @@ _latom_vec__indexi(lua_State *L, latom_t *latom)
}
static int
_latom_vec__indexk(lua_State *L, latom_t *latom)
_latom_vec__indexk(lua_State *L, latom_t *latom, const char *key)
{
const char *key = lua_tostring(L, 2);
if(!strcmp(key, "child_type"))
lua_pushinteger(L, latom->body.vec->child_type);
else if(!strcmp(key, "child_size"))
......@@ -1045,14 +1042,14 @@ _latom__index(lua_State *L)
lua_rawgeti(L, LUA_REGISTRYINDEX, UDATA_OFFSET + MOONY_UDATA_COUNT + MOONY_CCLOSURE_CLONE);
return 1;
}
else if(!strcmp(key, "write") && (latom->lheader.type == MOONY_UDATA_STASH) )
else if( (latom->lheader.type == MOONY_UDATA_STASH) && !strcmp(key, "write") )
{
lua_rawgeti(L, LUA_REGISTRYINDEX, UDATA_OFFSET + MOONY_UDATA_COUNT + MOONY_CCLOSURE_WRITE);
return 1;
}
else if(driver->__indexk)
{
return driver->__indexk(L, latom);
return driver->__indexk(L, latom, key);
}
}
else if(driver->__indexi && (type == LUA_TNUMBER) )
......
......@@ -27,10 +27,11 @@ typedef struct _ltuple_t ltuple_t;
typedef struct _lvec_t lvec_t;
typedef int (*latom_driver_function_t)(lua_State *L, latom_t *latom);
typedef int (*latom_driver_function_indexk_t)(lua_State *L, latom_t *latom, const char *key);
struct _latom_driver_t {
latom_driver_function_t __indexi;
latom_driver_function_t __indexk;
latom_driver_function_indexk_t __indexk;
latom_driver_function_t __len;
latom_driver_function_t __tostring;
latom_driver_function_t __call;
......@@ -87,11 +88,11 @@ struct _latom_t {
// in api_atom.c
extern const latom_driver_t latom_nil_driver;
extern const latom_driver_t latom_bool_driver;
extern const latom_driver_t latom_int_driver;
extern const latom_driver_t latom_long_driver;
extern const latom_driver_t latom_float_driver;
extern const latom_driver_t latom_double_driver;
extern const latom_driver_t latom_bool_driver;
extern const latom_driver_t latom_urid_driver;
extern const latom_driver_t latom_string_driver;
extern const latom_driver_t latom_literal_driver;
......@@ -100,9 +101,6 @@ extern const latom_driver_t latom_object_driver;
extern const latom_driver_t latom_vector_driver;
extern const latom_driver_t latom_sequence_driver;
extern const latom_driver_t latom_chunk_driver;
extern const latom_driver_t latom_char_driver;
extern const latom_driver_t latom_impulse_driver;
extern const latom_driver_t latom_rgba_driver;
extern const luaL_Reg latom_mt [];
......@@ -158,23 +156,15 @@ static inline const latom_driver_t *
_latom_driver(moony_t *moony, LV2_URID type)
{
const latom_driver_hash_t *base = moony->atom_driver_hash;
const latom_driver_hash_t *p;
for(size_t lim = DRIVER_HASH_MAX; lim != 0; lim >>= 1)
for(unsigned N = DRIVER_HASH_MAX, half; N > 1; N -= half)
{
p = base + (lim >> 1);
if(type == p->type)
return p->driver;
if(type > p->type)
{
base = p + 1;
lim--;
}
half = N/2;
const latom_driver_hash_t *dst = &base[half];
base = (dst->type > type) ? base : dst;
}
return &latom_chunk_driver;
return (base->type == type) ? base->driver : &latom_chunk_driver;
}
static void
......
......@@ -70,9 +70,9 @@ _loscresponder_method(const char *path, const LV2_Atom_Tuple *arguments, void *d
{
moony_t *moony = data;
lua_State *L = moony->vm.L;
LV2_Atom_Forge *forge = &moony->forge;
//LV2_Atom_Forge *forge = &moony->forge;
LV2_OSC_URID *osc_urid = &moony->osc_urid;
LV2_URID_Unmap *unmap = moony->unmap;
//LV2_URID_Unmap *unmap = moony->unmap;
// 1: uservalue
// 2: frames
......@@ -110,7 +110,7 @@ _loscresponder_method(const char *path, const LV2_Atom_Tuple *arguments, void *d
LV2_ATOM_TUPLE_FOREACH(arguments, atom)
{
const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom;
//const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom;
switch(lv2_osc_argument_type(osc_urid, atom))
{
......@@ -239,7 +239,7 @@ _loscresponder__call(lua_State *L)
lua_pop(L, 1); // atom
// check for valid atom and event type
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)latom->atom;
const LV2_Atom_Object *obj = latom ? (const LV2_Atom_Object *)latom->atom : NULL;
if( !latom
|| !lv2_atom_forge_is_object_type(&moony->forge, obj->atom.type)
......
......@@ -62,8 +62,8 @@
(iter) = lv2_atom_tuple_next(iter))
#endif
#define MOONY_MAX_CHUNK_LEN 0x10000 // 64KB
#define MOONY_MAX_ERROR_LEN 0x400 // 1KB
#define MOONY_MAX_CHUNK_LEN 0x20000 // 128KB
#define MOONY_MAX_ERROR_LEN 0x800 // 2KB
#define MOONY_URI "http://open-music-kontrollers.ch/lv2/moony"
......@@ -269,15 +269,14 @@ struct _moony_t {
LV2_Log_Log *log;
LV2_Log_Logger logger;
xpress_map_t *voice_map;
moony_vm_t vm;
char chunk [MOONY_MAX_CHUNK_LEN];
volatile int props_out;
volatile int dirty_out;
volatile int error_out;
volatile int trace_out;
char error [MOONY_MAX_ERROR_LEN];
char trace [MOONY_MAX_ERROR_LEN];
// udata cache
int itr [MOONY_UDATA_COUNT];
......@@ -293,7 +292,9 @@ struct _moony_t {
latom_driver_hash_t atom_driver_hash [DRIVER_HASH_MAX];
xpress_map_t *voice_map;
char error [MOONY_MAX_ERROR_LEN];
char trace [MOONY_MAX_ERROR_LEN];
char chunk [MOONY_MAX_CHUNK_LEN];
};
// in api.c
......
......@@ -99,7 +99,7 @@ moony:c1xc1
lv2:index 2 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -110,7 +110,7 @@ moony:c1xc1
lv2:index 3 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -173,7 +173,7 @@ moony:c2xc2
lv2:index 4 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -184,7 +184,7 @@ moony:c2xc2
lv2:index 5 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -277,7 +277,7 @@ moony:c4xc4
lv2:index 8 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -288,7 +288,7 @@ moony:c4xc4
lv2:index 9 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -343,7 +343,7 @@ moony:a1xa1
lv2:index 2 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -354,7 +354,7 @@ moony:a1xa1
lv2:index 3 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -431,7 +431,7 @@ moony:a2xa2
lv2:index 4 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -442,7 +442,7 @@ moony:a2xa2
lv2:index 5 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -563,7 +563,7 @@ moony:a4xa4
lv2:index 8 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -574,7 +574,7 @@ moony:a4xa4
lv2:index 9 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -660,7 +660,7 @@ moony:c1a1xc1a1
lv2:index 4 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -671,7 +671,7 @@ moony:c1a1xc1a1
lv2:index 5 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -762,7 +762,7 @@ moony:c2a1xc2a1
lv2:index 6 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -773,7 +773,7 @@ moony:c2a1xc2a1
lv2:index 7 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......@@ -894,7 +894,7 @@ moony:c4a1xc4a1
lv2:index 10 ;
lv2:symbol "control" ;
lv2:name "Control" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] , [
# output notify port
a lv2:OutputPort ,
......@@ -905,7 +905,7 @@ moony:c4a1xc4a1
lv2:index 11 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
rsz:minimumSize 65536 ;
rsz:minimumSize 131072 ;
] ;
state:state [
......
......@@ -253,14 +253,15 @@ main(int argc, char **argv)
lua_pushcclosure(L, _test, 1);
lua_setglobal(L, "test");
if(luaL_dofile(L, argv[1])) // wraps around lua_pcall
{
const int ret = luaL_dofile(L, argv[1]); // wraps around lua_pcall
if(ret)
fprintf(stderr, "err: %s\n", lua_tostring(L, -1));
return -1;
}
//FIXME if not, moony_manual.lua failes, strange indeed
//moony_deinit(&handle.moony);
for(urid_t *itm=handle.urids; itm->urid; itm++)
free(itm->uri);
return 0;
moony_deinit(&handle.moony);
return ret;
}
......@@ -583,7 +583,7 @@ do
local id = 0
local otype = Map['http://test.org#type']
local key1 = Map['http://test.org#key1']
local context2 = Map['http://test.org#context2']
local ctx2 = Map['http://test.org#ctx2']
local key2 = Map['http://test.org#key2']
local function producer(forge)
......@@ -593,7 +593,7 @@ do
assert(obj:key(key1):int(12) == obj)
obj:property(key2, context2):long(13)
obj:property(key2, ctx2):long(13)
assert(obj:pop() == nil)
end
......@@ -612,11 +612,11 @@ do
sub = atom[key2]
assert(sub.body == 13)
for key, context, sub in atom:foreach() do
for key, sub, ctx in atom:foreach() do
assert(atom[key].body == sub.body)
if(key == key2) then
assert(context == context2)
assert(ctx == ctx2)
end
end
end
......@@ -1061,7 +1061,6 @@ do
assert(#seq == 2)
local subseq = seq[1]
assert(subseq.type == Atom.Sequence)
assert(subseq.pad == 0)
assert(subseq.unit == Atom.beatTime)
assert(#subseq == 2)
......@@ -1073,7 +1072,6 @@ do
subseq = seq[2]
assert(subseq.type == Atom.Sequence)
assert(subseq.pad == 0)
assert(subseq.unit == 0)
assert(#subseq == 0)
assert(subseq[0] == nil)
......
......@@ -188,6 +188,13 @@ _spawn_invalidate_child(spawn_t *spawn)
static inline int
_spawn_spawn(spawn_t *spawn, char **args)
{
if(!args)
{
if(spawn->logger)
lv2_log_error(spawn->logger, "nil argument list\n");
return -1;
}
spawn->pid = fork();
if(spawn->pid == 0) // child
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment