1 package dbus
2
3 import (
4 "encoding/binary"
5 "io"
6 "reflect"
7 )
8
9 type decoder struct {
10 in io.Reader
11 order binary.ByteOrder
12 pos int
13 fds []int
14 }
15
16
17
18 func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
19 dec := new(decoder)
20 dec.in = in
21 dec.order = order
22 dec.fds = fds
23 return dec
24 }
25
26
27 func (dec *decoder) align(n int) {
28 if dec.pos%n != 0 {
29 newpos := (dec.pos + n - 1) & ^(n - 1)
30 empty := make([]byte, newpos-dec.pos)
31 if _, err := io.ReadFull(dec.in, empty); err != nil {
32 panic(err)
33 }
34 dec.pos = newpos
35 }
36 }
37
38
39 func (dec *decoder) binread(v interface{}) {
40 if err := binary.Read(dec.in, dec.order, v); err != nil {
41 panic(err)
42 }
43 }
44
45 func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
46 defer func() {
47 var ok bool
48 v := recover()
49 if err, ok = v.(error); ok {
50 if err == io.EOF || err == io.ErrUnexpectedEOF {
51 err = FormatError("unexpected EOF")
52 }
53 }
54 }()
55 vs = make([]interface{}, 0)
56 s := sig.str
57 for s != "" {
58 err, rem := validSingle(s, &depthCounter{})
59 if err != nil {
60 return nil, err
61 }
62 v := dec.decode(s[:len(s)-len(rem)], 0)
63 vs = append(vs, v)
64 s = rem
65 }
66 return vs, nil
67 }
68
69 func (dec *decoder) decode(s string, depth int) interface{} {
70 dec.align(alignment(typeFor(s)))
71 switch s[0] {
72 case 'y':
73 var b [1]byte
74 if _, err := dec.in.Read(b[:]); err != nil {
75 panic(err)
76 }
77 dec.pos++
78 return b[0]
79 case 'b':
80 i := dec.decode("u", depth).(uint32)
81 switch {
82 case i == 0:
83 return false
84 case i == 1:
85 return true
86 default:
87 panic(FormatError("invalid value for boolean"))
88 }
89 case 'n':
90 var i int16
91 dec.binread(&i)
92 dec.pos += 2
93 return i
94 case 'i':
95 var i int32
96 dec.binread(&i)
97 dec.pos += 4
98 return i
99 case 'x':
100 var i int64
101 dec.binread(&i)
102 dec.pos += 8
103 return i
104 case 'q':
105 var i uint16
106 dec.binread(&i)
107 dec.pos += 2
108 return i
109 case 'u':
110 var i uint32
111 dec.binread(&i)
112 dec.pos += 4
113 return i
114 case 't':
115 var i uint64
116 dec.binread(&i)
117 dec.pos += 8
118 return i
119 case 'd':
120 var f float64
121 dec.binread(&f)
122 dec.pos += 8
123 return f
124 case 's':
125 length := dec.decode("u", depth).(uint32)
126 b := make([]byte, int(length)+1)
127 if _, err := io.ReadFull(dec.in, b); err != nil {
128 panic(err)
129 }
130 dec.pos += int(length) + 1
131 return string(b[:len(b)-1])
132 case 'o':
133 return ObjectPath(dec.decode("s", depth).(string))
134 case 'g':
135 length := dec.decode("y", depth).(byte)
136 b := make([]byte, int(length)+1)
137 if _, err := io.ReadFull(dec.in, b); err != nil {
138 panic(err)
139 }
140 dec.pos += int(length) + 1
141 sig, err := ParseSignature(string(b[:len(b)-1]))
142 if err != nil {
143 panic(err)
144 }
145 return sig
146 case 'v':
147 if depth >= 64 {
148 panic(FormatError("input exceeds container depth limit"))
149 }
150 var variant Variant
151 sig := dec.decode("g", depth).(Signature)
152 if len(sig.str) == 0 {
153 panic(FormatError("variant signature is empty"))
154 }
155 err, rem := validSingle(sig.str, &depthCounter{})
156 if err != nil {
157 panic(err)
158 }
159 if rem != "" {
160 panic(FormatError("variant signature has multiple types"))
161 }
162 variant.sig = sig
163 variant.value = dec.decode(sig.str, depth+1)
164 return variant
165 case 'h':
166 idx := dec.decode("u", depth).(uint32)
167 if int(idx) < len(dec.fds) {
168 return UnixFD(dec.fds[idx])
169 }
170 return UnixFDIndex(idx)
171 case 'a':
172 if len(s) > 1 && s[1] == '{' {
173 ksig := s[2:3]
174 vsig := s[3 : len(s)-1]
175 v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
176 if depth >= 63 {
177 panic(FormatError("input exceeds container depth limit"))
178 }
179 length := dec.decode("u", depth).(uint32)
180
181 dec.align(8)
182 spos := dec.pos
183 for dec.pos < spos+int(length) {
184 dec.align(8)
185 if !isKeyType(v.Type().Key()) {
186 panic(InvalidTypeError{v.Type()})
187 }
188 kv := dec.decode(ksig, depth+2)
189 vv := dec.decode(vsig, depth+2)
190 v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
191 }
192 return v.Interface()
193 }
194 if depth >= 64 {
195 panic(FormatError("input exceeds container depth limit"))
196 }
197 sig := s[1:]
198 length := dec.decode("u", depth).(uint32)
199
200 var capacity int
201 if s := sigByteSize(sig); s != 0 {
202 capacity = int(length) / s
203 }
204 v := reflect.MakeSlice(reflect.SliceOf(typeFor(sig)), 0, capacity)
205
206 align := alignment(typeFor(s[1:]))
207 if len(s) > 1 && s[1] == '(' {
208
209
210
211 align = 8
212 }
213 dec.align(align)
214 spos := dec.pos
215 for dec.pos < spos+int(length) {
216 ev := dec.decode(s[1:], depth+1)
217 v = reflect.Append(v, reflect.ValueOf(ev))
218 }
219 return v.Interface()
220 case '(':
221 if depth >= 64 {
222 panic(FormatError("input exceeds container depth limit"))
223 }
224 dec.align(8)
225 v := make([]interface{}, 0)
226 s = s[1 : len(s)-1]
227 for s != "" {
228 err, rem := validSingle(s, &depthCounter{})
229 if err != nil {
230 panic(err)
231 }
232 ev := dec.decode(s[:len(s)-len(rem)], depth+1)
233 v = append(v, ev)
234 s = rem
235 }
236 return v
237 default:
238 panic(SignatureError{Sig: s})
239 }
240 }
241
242
243
244
245
246
247 func sigByteSize(sig string) int {
248 var total int
249 for offset := 0; offset < len(sig); {
250 switch sig[offset] {
251 case 'y':
252 total += 1
253 offset += 1
254 case 'n', 'q':
255 total += 2
256 offset += 1
257 case 'b', 'i', 'u', 'h':
258 total += 4
259 offset += 1
260 case 'x', 't', 'd':
261 total += 8
262 offset += 1
263 case '(':
264 i := 1
265 depth := 1
266 for i < len(sig[offset:]) && depth != 0 {
267 if sig[offset+i] == '(' {
268 depth++
269 } else if sig[offset+i] == ')' {
270 depth--
271 }
272 i++
273 }
274 s := sigByteSize(sig[offset+1 : offset+i-1])
275 if s == 0 {
276 return 0
277 }
278 total += s
279 offset += i
280 default:
281 return 0
282 }
283 }
284 return total
285 }
286
287
288 type FormatError string
289
290 func (e FormatError) Error() string {
291 return "dbus: wire format error: " + string(e)
292 }
293
View as plain text