1package dbus
2
3import (
4	"bytes"
5	"errors"
6	"fmt"
7	"io"
8	"reflect"
9	"strconv"
10	"strings"
11	"unicode/utf8"
12)
13
14type varParser struct {
15	tokens []varToken
16	i      int
17}
18
19func (p *varParser) backup() {
20	p.i--
21}
22
23func (p *varParser) next() varToken {
24	if p.i < len(p.tokens) {
25		t := p.tokens[p.i]
26		p.i++
27		return t
28	}
29	return varToken{typ: tokEOF}
30}
31
32type varNode interface {
33	Infer() (Signature, error)
34	String() string
35	Sigs() sigSet
36	Value(Signature) (interface{}, error)
37}
38
39func varMakeNode(p *varParser) (varNode, error) {
40	var sig Signature
41
42	for {
43		t := p.next()
44		switch t.typ {
45		case tokEOF:
46			return nil, io.ErrUnexpectedEOF
47		case tokError:
48			return nil, errors.New(t.val)
49		case tokNumber:
50			return varMakeNumNode(t, sig)
51		case tokString:
52			return varMakeStringNode(t, sig)
53		case tokBool:
54			if sig.str != "" && sig.str != "b" {
55				return nil, varTypeError{t.val, sig}
56			}
57			b, err := strconv.ParseBool(t.val)
58			if err != nil {
59				return nil, err
60			}
61			return boolNode(b), nil
62		case tokArrayStart:
63			return varMakeArrayNode(p, sig)
64		case tokVariantStart:
65			return varMakeVariantNode(p, sig)
66		case tokDictStart:
67			return varMakeDictNode(p, sig)
68		case tokType:
69			if sig.str != "" {
70				return nil, errors.New("unexpected type annotation")
71			}
72			if t.val[0] == '@' {
73				sig.str = t.val[1:]
74			} else {
75				sig.str = varTypeMap[t.val]
76			}
77		case tokByteString:
78			if sig.str != "" && sig.str != "ay" {
79				return nil, varTypeError{t.val, sig}
80			}
81			b, err := varParseByteString(t.val)
82			if err != nil {
83				return nil, err
84			}
85			return byteStringNode(b), nil
86		default:
87			return nil, fmt.Errorf("unexpected %q", t.val)
88		}
89	}
90}
91
92type varTypeError struct {
93	val string
94	sig Signature
95}
96
97func (e varTypeError) Error() string {
98	return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
99}
100
101type sigSet map[Signature]bool
102
103func (s sigSet) Empty() bool {
104	return len(s) == 0
105}
106
107func (s sigSet) Intersect(s2 sigSet) sigSet {
108	r := make(sigSet)
109	for k := range s {
110		if s2[k] {
111			r[k] = true
112		}
113	}
114	return r
115}
116
117func (s sigSet) Single() (Signature, bool) {
118	if len(s) == 1 {
119		for k := range s {
120			return k, true
121		}
122	}
123	return Signature{}, false
124}
125
126func (s sigSet) ToArray() sigSet {
127	r := make(sigSet, len(s))
128	for k := range s {
129		r[Signature{"a" + k.str}] = true
130	}
131	return r
132}
133
134type numNode struct {
135	sig Signature
136	str string
137	val interface{}
138}
139
140var numSigSet = sigSet{
141	Signature{"y"}: true,
142	Signature{"n"}: true,
143	Signature{"q"}: true,
144	Signature{"i"}: true,
145	Signature{"u"}: true,
146	Signature{"x"}: true,
147	Signature{"t"}: true,
148	Signature{"d"}: true,
149}
150
151func (n numNode) Infer() (Signature, error) {
152	if strings.ContainsAny(n.str, ".e") {
153		return Signature{"d"}, nil
154	}
155	return Signature{"i"}, nil
156}
157
158func (n numNode) String() string {
159	return n.str
160}
161
162func (n numNode) Sigs() sigSet {
163	if n.sig.str != "" {
164		return sigSet{n.sig: true}
165	}
166	if strings.ContainsAny(n.str, ".e") {
167		return sigSet{Signature{"d"}: true}
168	}
169	return numSigSet
170}
171
172func (n numNode) Value(sig Signature) (interface{}, error) {
173	if n.sig.str != "" && n.sig != sig {
174		return nil, varTypeError{n.str, sig}
175	}
176	if n.val != nil {
177		return n.val, nil
178	}
179	return varNumAs(n.str, sig)
180}
181
182func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
183	if sig.str == "" {
184		return numNode{str: tok.val}, nil
185	}
186	num, err := varNumAs(tok.val, sig)
187	if err != nil {
188		return nil, err
189	}
190	return numNode{sig: sig, val: num}, nil
191}
192
193func varNumAs(s string, sig Signature) (interface{}, error) {
194	isUnsigned := false
195	size := 32
196	switch sig.str {
197	case "n":
198		size = 16
199	case "i":
200	case "x":
201		size = 64
202	case "y":
203		size = 8
204		isUnsigned = true
205	case "q":
206		size = 16
207		isUnsigned = true
208	case "u":
209		isUnsigned = true
210	case "t":
211		size = 64
212		isUnsigned = true
213	case "d":
214		d, err := strconv.ParseFloat(s, 64)
215		if err != nil {
216			return nil, err
217		}
218		return d, nil
219	default:
220		return nil, varTypeError{s, sig}
221	}
222	base := 10
223	if strings.HasPrefix(s, "0x") {
224		base = 16
225		s = s[2:]
226	}
227	if strings.HasPrefix(s, "0") && len(s) != 1 {
228		base = 8
229		s = s[1:]
230	}
231	if isUnsigned {
232		i, err := strconv.ParseUint(s, base, size)
233		if err != nil {
234			return nil, err
235		}
236		var v interface{} = i
237		switch sig.str {
238		case "y":
239			v = byte(i)
240		case "q":
241			v = uint16(i)
242		case "u":
243			v = uint32(i)
244		}
245		return v, nil
246	}
247	i, err := strconv.ParseInt(s, base, size)
248	if err != nil {
249		return nil, err
250	}
251	var v interface{} = i
252	switch sig.str {
253	case "n":
254		v = int16(i)
255	case "i":
256		v = int32(i)
257	}
258	return v, nil
259}
260
261type stringNode struct {
262	sig Signature
263	str string      // parsed
264	val interface{} // has correct type
265}
266
267var stringSigSet = sigSet{
268	Signature{"s"}: true,
269	Signature{"g"}: true,
270	Signature{"o"}: true,
271}
272
273func (n stringNode) Infer() (Signature, error) {
274	return Signature{"s"}, nil
275}
276
277func (n stringNode) String() string {
278	return n.str
279}
280
281func (n stringNode) Sigs() sigSet {
282	if n.sig.str != "" {
283		return sigSet{n.sig: true}
284	}
285	return stringSigSet
286}
287
288func (n stringNode) Value(sig Signature) (interface{}, error) {
289	if n.sig.str != "" && n.sig != sig {
290		return nil, varTypeError{n.str, sig}
291	}
292	if n.val != nil {
293		return n.val, nil
294	}
295	switch {
296	case sig.str == "g":
297		return Signature{n.str}, nil
298	case sig.str == "o":
299		return ObjectPath(n.str), nil
300	case sig.str == "s":
301		return n.str, nil
302	default:
303		return nil, varTypeError{n.str, sig}
304	}
305}
306
307func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
308	if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
309		return nil, fmt.Errorf("invalid type %q for string", sig.str)
310	}
311	s, err := varParseString(tok.val)
312	if err != nil {
313		return nil, err
314	}
315	n := stringNode{str: s}
316	if sig.str == "" {
317		return stringNode{str: s}, nil
318	}
319	n.sig = sig
320	switch sig.str {
321	case "o":
322		n.val = ObjectPath(s)
323	case "g":
324		n.val = Signature{s}
325	case "s":
326		n.val = s
327	}
328	return n, nil
329}
330
331func varParseString(s string) (string, error) {
332	// quotes are guaranteed to be there
333	s = s[1 : len(s)-1]
334	buf := new(bytes.Buffer)
335	for len(s) != 0 {
336		r, size := utf8.DecodeRuneInString(s)
337		if r == utf8.RuneError && size == 1 {
338			return "", errors.New("invalid UTF-8")
339		}
340		s = s[size:]
341		if r != '\\' {
342			buf.WriteRune(r)
343			continue
344		}
345		r, size = utf8.DecodeRuneInString(s)
346		if r == utf8.RuneError && size == 1 {
347			return "", errors.New("invalid UTF-8")
348		}
349		s = s[size:]
350		switch r {
351		case 'a':
352			buf.WriteRune(0x7)
353		case 'b':
354			buf.WriteRune(0x8)
355		case 'f':
356			buf.WriteRune(0xc)
357		case 'n':
358			buf.WriteRune('\n')
359		case 'r':
360			buf.WriteRune('\r')
361		case 't':
362			buf.WriteRune('\t')
363		case '\n':
364		case 'u':
365			if len(s) < 4 {
366				return "", errors.New("short unicode escape")
367			}
368			r, err := strconv.ParseUint(s[:4], 16, 32)
369			if err != nil {
370				return "", err
371			}
372			buf.WriteRune(rune(r))
373			s = s[4:]
374		case 'U':
375			if len(s) < 8 {
376				return "", errors.New("short unicode escape")
377			}
378			r, err := strconv.ParseUint(s[:8], 16, 32)
379			if err != nil {
380				return "", err
381			}
382			buf.WriteRune(rune(r))
383			s = s[8:]
384		default:
385			buf.WriteRune(r)
386		}
387	}
388	return buf.String(), nil
389}
390
391var boolSigSet = sigSet{Signature{"b"}: true}
392
393type boolNode bool
394
395func (boolNode) Infer() (Signature, error) {
396	return Signature{"b"}, nil
397}
398
399func (b boolNode) String() string {
400	if b {
401		return "true"
402	}
403	return "false"
404}
405
406func (boolNode) Sigs() sigSet {
407	return boolSigSet
408}
409
410func (b boolNode) Value(sig Signature) (interface{}, error) {
411	if sig.str != "b" {
412		return nil, varTypeError{b.String(), sig}
413	}
414	return bool(b), nil
415}
416
417type arrayNode struct {
418	set      sigSet
419	children []varNode
420	val      interface{}
421}
422
423func (n arrayNode) Infer() (Signature, error) {
424	for _, v := range n.children {
425		csig, err := varInfer(v)
426		if err != nil {
427			continue
428		}
429		return Signature{"a" + csig.str}, nil
430	}
431	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
432}
433
434func (n arrayNode) String() string {
435	s := "["
436	for i, v := range n.children {
437		s += v.String()
438		if i != len(n.children)-1 {
439			s += ", "
440		}
441	}
442	return s + "]"
443}
444
445func (n arrayNode) Sigs() sigSet {
446	return n.set
447}
448
449func (n arrayNode) Value(sig Signature) (interface{}, error) {
450	if n.set.Empty() {
451		// no type information whatsoever, so this must be an empty slice
452		return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
453	}
454	if !n.set[sig] {
455		return nil, varTypeError{n.String(), sig}
456	}
457	s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
458	for i, v := range n.children {
459		rv, err := v.Value(Signature{sig.str[1:]})
460		if err != nil {
461			return nil, err
462		}
463		s.Index(i).Set(reflect.ValueOf(rv))
464	}
465	return s.Interface(), nil
466}
467
468func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
469	var n arrayNode
470	if sig.str != "" {
471		n.set = sigSet{sig: true}
472	}
473	if t := p.next(); t.typ == tokArrayEnd {
474		return n, nil
475	} else {
476		p.backup()
477	}
478Loop:
479	for {
480		t := p.next()
481		switch t.typ {
482		case tokEOF:
483			return nil, io.ErrUnexpectedEOF
484		case tokError:
485			return nil, errors.New(t.val)
486		}
487		p.backup()
488		cn, err := varMakeNode(p)
489		if err != nil {
490			return nil, err
491		}
492		if cset := cn.Sigs(); !cset.Empty() {
493			if n.set.Empty() {
494				n.set = cset.ToArray()
495			} else {
496				nset := cset.ToArray().Intersect(n.set)
497				if nset.Empty() {
498					return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
499				}
500				n.set = nset
501			}
502		}
503		n.children = append(n.children, cn)
504		switch t := p.next(); t.typ {
505		case tokEOF:
506			return nil, io.ErrUnexpectedEOF
507		case tokError:
508			return nil, errors.New(t.val)
509		case tokArrayEnd:
510			break Loop
511		case tokComma:
512			continue
513		default:
514			return nil, fmt.Errorf("unexpected %q", t.val)
515		}
516	}
517	return n, nil
518}
519
520type variantNode struct {
521	n varNode
522}
523
524var variantSet = sigSet{
525	Signature{"v"}: true,
526}
527
528func (variantNode) Infer() (Signature, error) {
529	return Signature{"v"}, nil
530}
531
532func (n variantNode) String() string {
533	return "<" + n.n.String() + ">"
534}
535
536func (variantNode) Sigs() sigSet {
537	return variantSet
538}
539
540func (n variantNode) Value(sig Signature) (interface{}, error) {
541	if sig.str != "v" {
542		return nil, varTypeError{n.String(), sig}
543	}
544	sig, err := varInfer(n.n)
545	if err != nil {
546		return nil, err
547	}
548	v, err := n.n.Value(sig)
549	if err != nil {
550		return nil, err
551	}
552	return MakeVariant(v), nil
553}
554
555func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
556	n, err := varMakeNode(p)
557	if err != nil {
558		return nil, err
559	}
560	if t := p.next(); t.typ != tokVariantEnd {
561		return nil, fmt.Errorf("unexpected %q", t.val)
562	}
563	vn := variantNode{n}
564	if sig.str != "" && sig.str != "v" {
565		return nil, varTypeError{vn.String(), sig}
566	}
567	return variantNode{n}, nil
568}
569
570type dictEntry struct {
571	key, val varNode
572}
573
574type dictNode struct {
575	kset, vset sigSet
576	children   []dictEntry
577	val        interface{}
578}
579
580func (n dictNode) Infer() (Signature, error) {
581	for _, v := range n.children {
582		ksig, err := varInfer(v.key)
583		if err != nil {
584			continue
585		}
586		vsig, err := varInfer(v.val)
587		if err != nil {
588			continue
589		}
590		return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
591	}
592	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
593}
594
595func (n dictNode) String() string {
596	s := "{"
597	for i, v := range n.children {
598		s += v.key.String() + ": " + v.val.String()
599		if i != len(n.children)-1 {
600			s += ", "
601		}
602	}
603	return s + "}"
604}
605
606func (n dictNode) Sigs() sigSet {
607	r := sigSet{}
608	for k := range n.kset {
609		for v := range n.vset {
610			sig := "a{" + k.str + v.str + "}"
611			r[Signature{sig}] = true
612		}
613	}
614	return r
615}
616
617func (n dictNode) Value(sig Signature) (interface{}, error) {
618	set := n.Sigs()
619	if set.Empty() {
620		// no type information -> empty dict
621		return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
622	}
623	if !set[sig] {
624		return nil, varTypeError{n.String(), sig}
625	}
626	m := reflect.MakeMap(typeFor(sig.str))
627	ksig := Signature{sig.str[2:3]}
628	vsig := Signature{sig.str[3 : len(sig.str)-1]}
629	for _, v := range n.children {
630		kv, err := v.key.Value(ksig)
631		if err != nil {
632			return nil, err
633		}
634		vv, err := v.val.Value(vsig)
635		if err != nil {
636			return nil, err
637		}
638		m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
639	}
640	return m.Interface(), nil
641}
642
643func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
644	var n dictNode
645
646	if sig.str != "" {
647		if len(sig.str) < 5 {
648			return nil, fmt.Errorf("invalid signature %q for dict type", sig)
649		}
650		ksig := Signature{string(sig.str[2])}
651		vsig := Signature{sig.str[3 : len(sig.str)-1]}
652		n.kset = sigSet{ksig: true}
653		n.vset = sigSet{vsig: true}
654	}
655	if t := p.next(); t.typ == tokDictEnd {
656		return n, nil
657	} else {
658		p.backup()
659	}
660Loop:
661	for {
662		t := p.next()
663		switch t.typ {
664		case tokEOF:
665			return nil, io.ErrUnexpectedEOF
666		case tokError:
667			return nil, errors.New(t.val)
668		}
669		p.backup()
670		kn, err := varMakeNode(p)
671		if err != nil {
672			return nil, err
673		}
674		if kset := kn.Sigs(); !kset.Empty() {
675			if n.kset.Empty() {
676				n.kset = kset
677			} else {
678				n.kset = kset.Intersect(n.kset)
679				if n.kset.Empty() {
680					return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
681				}
682			}
683		}
684		t = p.next()
685		switch t.typ {
686		case tokEOF:
687			return nil, io.ErrUnexpectedEOF
688		case tokError:
689			return nil, errors.New(t.val)
690		case tokColon:
691		default:
692			return nil, fmt.Errorf("unexpected %q", t.val)
693		}
694		t = p.next()
695		switch t.typ {
696		case tokEOF:
697			return nil, io.ErrUnexpectedEOF
698		case tokError:
699			return nil, errors.New(t.val)
700		}
701		p.backup()
702		vn, err := varMakeNode(p)
703		if err != nil {
704			return nil, err
705		}
706		if vset := vn.Sigs(); !vset.Empty() {
707			if n.vset.Empty() {
708				n.vset = vset
709			} else {
710				n.vset = n.vset.Intersect(vset)
711				if n.vset.Empty() {
712					return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
713				}
714			}
715		}
716		n.children = append(n.children, dictEntry{kn, vn})
717		t = p.next()
718		switch t.typ {
719		case tokEOF:
720			return nil, io.ErrUnexpectedEOF
721		case tokError:
722			return nil, errors.New(t.val)
723		case tokDictEnd:
724			break Loop
725		case tokComma:
726			continue
727		default:
728			return nil, fmt.Errorf("unexpected %q", t.val)
729		}
730	}
731	return n, nil
732}
733
734type byteStringNode []byte
735
736var byteStringSet = sigSet{
737	Signature{"ay"}: true,
738}
739
740func (byteStringNode) Infer() (Signature, error) {
741	return Signature{"ay"}, nil
742}
743
744func (b byteStringNode) String() string {
745	return string(b)
746}
747
748func (b byteStringNode) Sigs() sigSet {
749	return byteStringSet
750}
751
752func (b byteStringNode) Value(sig Signature) (interface{}, error) {
753	if sig.str != "ay" {
754		return nil, varTypeError{b.String(), sig}
755	}
756	return []byte(b), nil
757}
758
759func varParseByteString(s string) ([]byte, error) {
760	// quotes and b at start are guaranteed to be there
761	b := make([]byte, 0, 1)
762	s = s[2 : len(s)-1]
763	for len(s) != 0 {
764		c := s[0]
765		s = s[1:]
766		if c != '\\' {
767			b = append(b, c)
768			continue
769		}
770		c = s[0]
771		s = s[1:]
772		switch c {
773		case 'a':
774			b = append(b, 0x7)
775		case 'b':
776			b = append(b, 0x8)
777		case 'f':
778			b = append(b, 0xc)
779		case 'n':
780			b = append(b, '\n')
781		case 'r':
782			b = append(b, '\r')
783		case 't':
784			b = append(b, '\t')
785		case 'x':
786			if len(s) < 2 {
787				return nil, errors.New("short escape")
788			}
789			n, err := strconv.ParseUint(s[:2], 16, 8)
790			if err != nil {
791				return nil, err
792			}
793			b = append(b, byte(n))
794			s = s[2:]
795		case '0':
796			if len(s) < 3 {
797				return nil, errors.New("short escape")
798			}
799			n, err := strconv.ParseUint(s[:3], 8, 8)
800			if err != nil {
801				return nil, err
802			}
803			b = append(b, byte(n))
804			s = s[3:]
805		default:
806			b = append(b, c)
807		}
808	}
809	return append(b, 0), nil
810}
811
812func varInfer(n varNode) (Signature, error) {
813	if sig, ok := n.Sigs().Single(); ok {
814		return sig, nil
815	}
816	return n.Infer()
817}
818