lua/api: fix client update_permissions()
* the type checks were wrong, it was requiring the key to be string and the value integer * add the ability to use "any" or "all" for a key, saving us the trouble of passing -1 from lua (int64) into a uint32 (ugh!) * use a GArray instead of manual malloc/realloc * allocate the array as late as possible, to minimize the risk of leaking its memory if we hit luaL_error()
This commit is contained in:
@@ -891,35 +891,25 @@ impl_node_new (lua_State *L)
|
|||||||
static gboolean
|
static gboolean
|
||||||
client_parse_permissions (const gchar * perms_str, guint32 *perms)
|
client_parse_permissions (const gchar * perms_str, guint32 *perms)
|
||||||
{
|
{
|
||||||
guint32 res = 0;
|
*perms = 0;
|
||||||
|
|
||||||
if (g_strcmp0 (perms_str, "all") == 0) {
|
if (!perms_str)
|
||||||
res = PW_PERM_ALL;
|
return FALSE;
|
||||||
} else {
|
else if (g_strcmp0 (perms_str, "all") == 0)
|
||||||
|
*perms = PW_PERM_ALL;
|
||||||
|
else {
|
||||||
for (guint i = 0; i < strlen (perms_str); i++) {
|
for (guint i = 0; i < strlen (perms_str); i++) {
|
||||||
switch (perms_str[i]) {
|
switch (perms_str[i]) {
|
||||||
case 'r':
|
case 'r': *perms |= PW_PERM_R; break;
|
||||||
res |= PW_PERM_R;
|
case 'w': *perms |= PW_PERM_W; break;
|
||||||
break;
|
case 'x': *perms |= PW_PERM_X; break;
|
||||||
case 'w':
|
case 'm': *perms |= PW_PERM_M; break;
|
||||||
res |= PW_PERM_W;
|
case '-': break;
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
res |= PW_PERM_X;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
res |= PW_PERM_M;
|
|
||||||
case '-':
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perms)
|
|
||||||
*perms = res;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,35 +917,35 @@ static int
|
|||||||
client_update_permissions (lua_State *L)
|
client_update_permissions (lua_State *L)
|
||||||
{
|
{
|
||||||
WpClient *client = wplua_checkobject (L, 1, WP_TYPE_CLIENT);
|
WpClient *client = wplua_checkobject (L, 1, WP_TYPE_CLIENT);
|
||||||
guint n_perm = 0;
|
g_autoptr (GArray) arr = NULL;
|
||||||
guint size = 16;
|
|
||||||
g_autofree struct pw_permission *arr =
|
|
||||||
g_malloc0_n (size, sizeof (struct pw_permission));
|
|
||||||
|
|
||||||
luaL_checktype (L, 2, LUA_TTABLE);
|
luaL_checktype (L, 2, LUA_TTABLE);
|
||||||
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next (L, -2)) {
|
while (lua_next (L, -2)) {
|
||||||
if (lua_type (L, -1) == LUA_TNUMBER && lua_type (L, -2) == LUA_TSTRING) {
|
struct pw_permission perm = {0};
|
||||||
guint32 id = lua_tointeger (L, -2);
|
|
||||||
const gchar *perms_str = lua_tostring (L, -1);
|
if (lua_type (L, -2) == LUA_TSTRING &&
|
||||||
guint32 perms = 0;
|
(!g_ascii_strcasecmp (lua_tostring(L, -2), "any") ||
|
||||||
if (client_parse_permissions (perms_str, &perms)) {
|
!g_ascii_strcasecmp (lua_tostring(L, -2), "all")))
|
||||||
if (size < n_perm) {
|
perm.id = PW_ID_ANY;
|
||||||
size += 16;
|
else if (lua_isinteger (L, -2))
|
||||||
arr = g_realloc (arr, size * sizeof (struct pw_permission));
|
perm.id = lua_tointeger (L, -2);
|
||||||
}
|
else
|
||||||
arr[n_perm].id = id;
|
luaL_error (L, "invalid key for permissions array");
|
||||||
arr[n_perm].permissions = perms;
|
|
||||||
n_perm++;
|
if (!client_parse_permissions (lua_tostring (L, -1), &perm.permissions))
|
||||||
} else {
|
luaL_error (L, "invalid permission string: '%s'", lua_tostring (L, -1));
|
||||||
wp_warning ("Ignored invalid permission '%s'", perms_str);
|
|
||||||
}
|
if (!arr)
|
||||||
}
|
arr = g_array_new (FALSE, FALSE, sizeof (struct pw_permission));
|
||||||
|
|
||||||
|
g_array_append_val (arr, perm);
|
||||||
lua_pop (L, 1);
|
lua_pop (L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_client_update_permissions_array (client, n_perm, arr);
|
wp_client_update_permissions_array (client, arr->len,
|
||||||
|
(const struct pw_permission *) arr->data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user