Skip to content

Commit 63fea7c

Browse files
author
Rafael Gago
committed
ldbus: Fix iter_args
on the ldbus backend "iter_args" was completely broken for complex types, calling a function returning "a{sa{sv}}" like e.g. "org.freedesktop.NetworkmManager.Settings.Connection.GetSettings" failed completely. This patch reimplements "iter_args" correctly.
1 parent c681e15 commit 63fea7c

File tree

1 file changed

+40
-40
lines changed

1 file changed

+40
-40
lines changed

awesome/dbus.lua

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -102,52 +102,52 @@ function dbus.process_request(req)
102102
return true
103103
end
104104

105-
function dbus.iter_args(iter, alltype)
106-
local args = { len = 0 }
105+
function dbus.iter_args(iter, args_dst)
106+
local args = args_dst or {}
107107
if not iter then return args end
108-
typ = alltype or iter:get_arg_type()
109-
while true do
110-
if not typ then
111-
args.len = args.len + 1
112-
args[args.len] = nil
113-
elseif typ == ldbus.types.variant then
114-
local nargs = dbus.iter_args(iter:recurse())
115-
for i = 1, nargs.len do
116-
args[args.len + i] = nargs[i]
117-
end
118-
args.len = args.len + nargs.len
119-
elseif typ == ldbus.types.dict_entry then
120-
local nargs = dbus.iter_args(iter:recurse())
121-
local kwargs = {}
122-
for i = 1, nargs.len, 2 do
123-
kwargs[nargs[i]] = nargs[i + 1]
108+
local typ = iter:get_arg_type()
109+
110+
while typ do
111+
local nextval = {}
112+
if typ == ldbus.types.array then
113+
local arr_typ = iter:get_element_type()
114+
if arr_typ == ldbus.types.dict_entry then
115+
local arr_it = iter:recurse()
116+
while arr_it:get_arg_type() do
117+
local de_it = arr_it:recurse()
118+
--assert (dbus.raw.set_of_basic_types[de_it:get_arg_type()])
119+
local key = de_it:get_basic()
120+
--assert (de_it:has_next()) --value is mandatory
121+
de_it:next()
122+
local val = dbus.iter_args(de_it)
123+
--assert(#val <= 1) --recursing on one dbus type
124+
nextval[key] = val[1]
125+
--assert (not de_it:has_next())
126+
arr_it:next()
127+
end
128+
elseif arr_typ then
129+
local arr_it = iter:recurse()
130+
while arr_it:get_arg_type() do
131+
-- more than one type can be returned, direct "nextval" write
132+
dbus.iter_args(arr_it, nextval)
133+
arr_it:next()
134+
end
124135
end
125-
args.packed = true
126-
args.len = args.len + 1
127-
args[args.len] = kwargs
136+
elseif typ == ldbus.types.variant then
137+
local val = dbus.iter_args(iter:recurse())
138+
--assert(#val <= 1) --recursing on only one dbus type
139+
nextval = val[1]
128140
elseif typ == ldbus.types.struct then
129-
local nargs = dbus.iter_args(iter:recurse())
130-
args.len = args.len + 1
131-
args[args.len] = nargs
132-
elseif typ == ldbus.types.array then
133-
local nargs = dbus.iter_args(iter:recurse(), iter:get_element_type())
134-
args.len = args.len + 1
135-
args[args.len] = nargs
136-
else
137-
args.len = args.len + 1
138-
args[args.len] = iter:get_basic()
139-
end
140-
if iter:next() then
141-
typ = alltype or iter:get_arg_type()
141+
--struct representation is an array of "n" values
142+
nextval = dbus.iter_args(iter:recurse())
142143
else
143-
break
144+
nextval = iter:get_basic()
144145
end
146+
table.insert(args, nextval)
147+
iter:next()
148+
typ = iter:get_arg_type()
145149
end
146-
if args.packed then
147-
return unpack(args)
148-
else
149-
return args
150-
end
150+
return args
151151
end
152152

153153
function dbus.type(value)

0 commit comments

Comments
 (0)