go-tg-screenshot-bot

Форк
0
292 строки · 6.5 Кб
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
// newDecoder returns a new decoder that reads values from in. The input is
17
// expected to be in the given byte order.
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
// align aligns the input to the given boundary and panics on error.
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
// Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
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
			// Even for empty maps, the correct padding must be included
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
		// capacity can be determined only for fixed-size element types
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
		// Even for empty arrays, the correct padding must be included
206
		align := alignment(typeFor(s[1:]))
207
		if len(s) > 1 && s[1] == '(' {
208
			//Special case for arrays of structs
209
			//structs decode as a slice of interface{} values
210
			//but the dbus alignment does not match this
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
// sigByteSize tries to calculates size of the given signature in bytes.
243
//
244
// It returns zero when it can't, for example when it contains non-fixed size
245
// types such as strings, maps and arrays that require reading of the transmitted
246
// data, for that we would need to implement the unread method for Decoder first.
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
// A FormatError is an error in the wire format.
288
type FormatError string
289

290
func (e FormatError) Error() string {
291
	return "dbus: wire format error: " + string(e)
292
}
293

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.