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