lua: workaround false positive dereference of null pointer
[project/ubus.git] / lua / ubus.c
index f59af90c20d10debc874a68d086b9bf781d25fff..fb50418d27b0e3c3ace535050a4f107b984c6d64 100644 (file)
@@ -52,11 +52,11 @@ static int
 ubus_lua_parse_blob(lua_State *L, struct blob_attr *attr, bool table);
 
 static int
-ubus_lua_parse_blob_array(lua_State *L, struct blob_attr *attr, int len, bool table)
+ubus_lua_parse_blob_array(lua_State *L, struct blob_attr *attr, size_t len, bool table)
 {
        int rv;
        int idx = 1;
-       int rem = len;
+       size_t rem = len;
        struct blob_attr *pos;
 
        lua_newtable(L);
@@ -111,6 +111,17 @@ ubus_lua_parse_blob(lua_State *L, struct blob_attr *attr, bool table)
                lua_pushnumber(L, (double) be64_to_cpu(*(uint64_t *)data));
                break;
 
+       case BLOBMSG_TYPE_DOUBLE:
+               {
+                       union {
+                               double d;
+                               uint64_t u64;
+                       } v;
+                       v.u64 = be64_to_cpu(*(uint64_t *)data);
+                       lua_pushnumber(L, v.d);
+               }
+               break;
+
        case BLOBMSG_TYPE_STRING:
                lua_pushstring(L, data);
                break;
@@ -352,6 +363,26 @@ static int ubus_lua_reply(lua_State *L)
        return 0;
 }
 
+static int ubus_lua_defer_request(lua_State *L)
+{
+       struct ubus_lua_connection *c = luaL_checkudata(L, 1, METANAME);
+       struct ubus_request_data *req = lua_touserdata(L, 2);
+       struct ubus_request_data *new_req = lua_newuserdata(L, sizeof(struct ubus_request_data));
+       ubus_defer_request(c->ctx, req, new_req);
+
+       return 1;
+}
+
+static int ubus_lua_complete_deferred_request(lua_State *L)
+{
+       struct ubus_lua_connection *c = luaL_checkudata(L, 1, METANAME);
+       struct ubus_request_data *req = lua_touserdata(L, 2);
+       int ret = luaL_checkinteger(L, 3);
+       ubus_complete_deferred_request(c->ctx, req, ret);
+
+       return 0;
+}
+
 static int ubus_lua_load_methods(lua_State *L, struct ubus_method *m)
 {
        struct blobmsg_policy *p;
@@ -390,11 +421,10 @@ static int ubus_lua_load_methods(lua_State *L, struct ubus_method *m)
        }
 
        /* setup the policy pointers */
-       p = malloc(sizeof(struct blobmsg_policy) * plen);
+       p = calloc(plen, sizeof(struct blobmsg_policy));
        if (!p)
                return 1;
 
-       memset(p, 0, sizeof(struct blobmsg_policy) * plen);
        m->policy = p;
        lua_pushnil(L);
        while (lua_next(L, -2) != 0) {
@@ -461,26 +491,23 @@ static struct ubus_object* ubus_lua_load_object(lua_State *L)
        int midx = 0;
 
        /* setup object pointers */
-       obj = malloc(sizeof(struct ubus_lua_object));
+       obj = calloc(1, sizeof(struct ubus_lua_object));
        if (!obj)
                return NULL;
 
-       memset(obj, 0, sizeof(struct ubus_lua_object));
        obj->o.name = lua_tostring(L, -2);
 
        /* setup method pointers */
-       m = malloc(sizeof(struct ubus_method) * mlen);
-       memset(m, 0, sizeof(struct ubus_method) * mlen);
+       m = calloc(mlen, sizeof(struct ubus_method));
        obj->o.methods = m;
 
        /* setup type pointers */
-       obj->o.type = malloc(sizeof(struct ubus_object_type));
+       obj->o.type = calloc(1, sizeof(struct ubus_object_type));
        if (!obj->o.type) {
                free(obj);
                return NULL;
        }
 
-       memset(obj->o.type, 0, sizeof(struct ubus_object_type));
        obj->o.type->name = lua_tostring(L, -2);
        obj->o.type->id = 0;
        obj->o.type->methods = obj->o.methods;
@@ -530,8 +557,7 @@ static int ubus_lua_add(lua_State *L)
        /* verify top level object */
        if (lua_istable(L, 1)) {
                lua_pushstring(L, "you need to pass a table");
-               lua_error(L);
-               return 0;
+               return lua_error(L);
        }
 
        /* scan each object */
@@ -571,7 +597,7 @@ ubus_lua_notify( lua_State *L )
 
        if( !lua_islightuserdata( L, 2 ) ){
                lua_pushfstring( L, "Invald 2nd parameter, expected ubus obj ref" );
-               lua_error( L );
+               return lua_error( L );
        }
        obj = lua_touserdata( L, 2 );
 
@@ -579,7 +605,7 @@ ubus_lua_notify( lua_State *L )
        blob_buf_init(&c->buf, 0);
        if( !ubus_lua_format_blob_array( L, &c->buf, true ) ){
                lua_pushfstring( L, "Invalid 4th parameter, expected table of arguments" );
-               lua_error( L );
+               return lua_error( L );
        }
 
        ubus_notify( c->ctx, obj, method, c->buf.head, -1 );
@@ -695,11 +721,10 @@ ubus_lua_load_event(lua_State *L)
 {
        struct ubus_lua_event* event = NULL;
 
-       event = malloc(sizeof(struct ubus_lua_event));
+       event = calloc(1, sizeof(struct ubus_lua_event));
        if (!event)
                return NULL;
 
-       memset(event, 0, sizeof(struct ubus_lua_event));
        event->e.cb = ubus_event_handler;
 
        /* update the he callback lookup table */
@@ -772,10 +797,11 @@ ubus_sub_notify_handler(struct ubus_context *ctx, struct ubus_object *obj,
        if (lua_isfunction(state, -1)) {
                if( msg ){
                        ubus_lua_parse_blob_array(state, blob_data(msg), blob_len(msg), true);
-                       lua_call(state, 1, 0);
                } else {
-                       lua_call(state, 0, 0);
+                       lua_pushnil(state);
                }
+               lua_pushstring(state, method);
+               lua_call(state, 2, 0);
        } else {
                lua_pop(state, 1);
        }
@@ -785,7 +811,7 @@ ubus_sub_notify_handler(struct ubus_context *ctx, struct ubus_object *obj,
 
 
 
-static void
+static int
 ubus_lua_do_subscribe( struct ubus_context *ctx, lua_State *L, const char* target,
                         int idxnotify, int idxremove )
 {
@@ -795,14 +821,13 @@ ubus_lua_do_subscribe( struct ubus_context *ctx, lua_State *L, const char* targe
 
        if( ( status = ubus_lookup_id( ctx, target, &id ) ) ){
                lua_pushfstring( L, "Unable find target, status=%d", status );
-               lua_error( L );
+               return lua_error( L );
        }
 
-       sub = malloc( sizeof( struct ubus_lua_subscriber ) );
-       memset( sub, 0, sizeof( struct ubus_lua_subscriber ) );
+       sub = calloc( 1, sizeof( struct ubus_lua_subscriber ) );
        if( !sub ){
                lua_pushstring( L, "Out of memory" );
-               lua_error( L );
+               return lua_error( L );
        }
 
        if( idxnotify ){
@@ -823,13 +848,15 @@ ubus_lua_do_subscribe( struct ubus_context *ctx, lua_State *L, const char* targe
 
        if( ( status = ubus_register_subscriber( ctx, &sub->s ) ) ){
                lua_pushfstring( L, "Failed to register subscriber, status=%d", status );
-               lua_error( L );
+               return lua_error( L );
        }
 
        if( ( status = ubus_subscribe( ctx, &sub->s, id) ) ){
                lua_pushfstring( L, "Failed to register subscriber, status=%d", status );
-               lua_error( L );
+               return lua_error( L );
        }
+
+       return 0;
 }
 
 static int
@@ -920,6 +947,8 @@ static const luaL_Reg ubus[] = {
        { "add", ubus_lua_add },
        { "notify", ubus_lua_notify },
        { "reply", ubus_lua_reply },
+       { "defer_request", ubus_lua_defer_request },
+       { "complete_deferred_request", ubus_lua_complete_deferred_request },
        { "signatures", ubus_lua_signatures },
        { "call", ubus_lua_call },
        { "close", ubus_lua__gc },
@@ -965,6 +994,8 @@ luaopen_ubus(lua_State *L)
        lua_setfield(L, -2, "INT16");
        lua_pushinteger(L, BLOBMSG_TYPE_INT8);
        lua_setfield(L, -2, "INT8");
+       lua_pushinteger(L, BLOBMSG_TYPE_DOUBLE);
+       lua_setfield(L, -2, "DOUBLE");
        lua_pushinteger(L, BLOBMSG_TYPE_BOOL);
        lua_setfield(L, -2, "BOOLEAN");