decoder.go (17231B)
1 package form 2 3 import ( 4 "fmt" 5 "log" 6 "net/url" 7 "reflect" 8 "strconv" 9 "time" 10 ) 11 12 const ( 13 errArraySize = "Array size of '%d' is larger than the maximum currently set on the decoder of '%d'. To increase this limit please see, SetMaxArraySize(size uint)" 14 errMissingStartBracket = "Invalid formatting for key '%s' missing '[' bracket" 15 errMissingEndBracket = "Invalid formatting for key '%s' missing ']' bracket" 16 ) 17 18 type decoder struct { 19 d *Decoder 20 errs DecodeErrors 21 dm dataMap 22 values url.Values 23 maxKeyLen int 24 namespace []byte 25 } 26 27 func (d *decoder) setError(namespace []byte, err error) { 28 if d.errs == nil { 29 d.errs = make(DecodeErrors) 30 } 31 d.errs[string(namespace)] = err 32 } 33 34 func (d *decoder) findAlias(ns string) *recursiveData { 35 for i := 0; i < len(d.dm); i++ { 36 if d.dm[i].alias == ns { 37 return d.dm[i] 38 } 39 } 40 return nil 41 } 42 43 func (d *decoder) parseMapData() { 44 // already parsed 45 if len(d.dm) > 0 { 46 return 47 } 48 49 d.maxKeyLen = 0 50 d.dm = d.dm[0:0] 51 52 var i int 53 var idx int 54 var l int 55 var insideBracket bool 56 var rd *recursiveData 57 var isNum bool 58 59 for k := range d.values { 60 61 if len(k) > d.maxKeyLen { 62 d.maxKeyLen = len(k) 63 } 64 65 for i = 0; i < len(k); i++ { 66 67 switch k[i] { 68 case '[': 69 idx = i 70 insideBracket = true 71 isNum = true 72 case ']': 73 74 if !insideBracket { 75 log.Panicf(errMissingStartBracket, k) 76 } 77 78 if rd = d.findAlias(k[:idx]); rd == nil { 79 80 l = len(d.dm) + 1 81 82 if l > cap(d.dm) { 83 dm := make(dataMap, l) 84 copy(dm, d.dm) 85 rd = new(recursiveData) 86 dm[len(d.dm)] = rd 87 d.dm = dm 88 } else { 89 l = len(d.dm) 90 d.dm = d.dm[:l+1] 91 rd = d.dm[l] 92 rd.sliceLen = 0 93 rd.keys = rd.keys[0:0] 94 } 95 96 rd.alias = k[:idx] 97 } 98 99 // is map + key 100 ke := key{ 101 ivalue: -1, 102 value: k[idx+1 : i], 103 searchValue: k[idx : i+1], 104 } 105 106 // is key is number, most likely array key, keep track of just in case an array/slice. 107 if isNum { 108 109 // no need to check for error, it will always pass 110 // as we have done the checking to ensure 111 // the value is a number ahead of time. 112 ke.ivalue, _ = strconv.Atoi(ke.value) 113 114 if ke.ivalue > rd.sliceLen { 115 rd.sliceLen = ke.ivalue 116 117 } 118 } 119 120 rd.keys = append(rd.keys, ke) 121 122 insideBracket = false 123 default: 124 // checking if not a number, 0-9 is 48-57 in byte, see for yourself fmt.Println('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') 125 if insideBracket && (k[i] > 57 || k[i] < 48) { 126 isNum = false 127 } 128 } 129 } 130 131 // if still inside bracket, that means no ending bracket was ever specified 132 if insideBracket { 133 log.Panicf(errMissingEndBracket, k) 134 } 135 } 136 } 137 138 func (d *decoder) traverseStruct(v reflect.Value, typ reflect.Type, namespace []byte) (set bool) { 139 140 l := len(namespace) 141 first := l == 0 142 143 // anonymous structs will still work for caching as the whole definition is stored 144 // including tags 145 s, ok := d.d.structCache.Get(typ) 146 if !ok { 147 s = d.d.structCache.parseStruct(d.d.mode, v, typ, d.d.tagName) 148 } 149 150 for _, f := range s.fields { 151 namespace = namespace[:l] 152 153 if f.isAnonymous { 154 if d.setFieldByType(v.Field(f.idx), namespace, 0) { 155 set = true 156 } 157 } 158 159 if first { 160 namespace = append(namespace, f.name...) 161 } else { 162 namespace = append(namespace, d.d.namespacePrefix...) 163 namespace = append(namespace, f.name...) 164 namespace = append(namespace, d.d.namespaceSuffix...) 165 } 166 167 if d.setFieldByType(v.Field(f.idx), namespace, 0) { 168 set = true 169 } 170 } 171 172 return 173 } 174 175 func (d *decoder) setFieldByType(current reflect.Value, namespace []byte, idx int) (set bool) { 176 177 var err error 178 v, kind := ExtractType(current) 179 180 arr, ok := d.values[string(namespace)] 181 182 if d.d.customTypeFuncs != nil { 183 184 if ok { 185 if cf, ok := d.d.customTypeFuncs[v.Type()]; ok { 186 val, err := cf(arr[idx:]) 187 if err != nil { 188 d.setError(namespace, err) 189 return 190 } 191 192 v.Set(reflect.ValueOf(val)) 193 set = true 194 return 195 } 196 } 197 } 198 switch kind { 199 case reflect.Interface: 200 if !ok || idx == len(arr) { 201 return 202 } 203 v.Set(reflect.ValueOf(arr[idx])) 204 set = true 205 206 case reflect.Ptr: 207 newVal := reflect.New(v.Type().Elem()) 208 if set = d.setFieldByType(newVal.Elem(), namespace, idx); set { 209 v.Set(newVal) 210 } 211 212 case reflect.String: 213 if !ok || idx == len(arr) { 214 return 215 } 216 v.SetString(arr[idx]) 217 set = true 218 219 case reflect.Uint, reflect.Uint64: 220 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 221 return 222 } 223 var u64 uint64 224 if u64, err = strconv.ParseUint(arr[idx], 10, 64); err != nil { 225 d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 226 return 227 } 228 v.SetUint(u64) 229 set = true 230 231 case reflect.Uint8: 232 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 233 return 234 } 235 var u64 uint64 236 if u64, err = strconv.ParseUint(arr[idx], 10, 8); err != nil { 237 d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 238 return 239 } 240 v.SetUint(u64) 241 set = true 242 243 case reflect.Uint16: 244 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 245 return 246 } 247 var u64 uint64 248 if u64, err = strconv.ParseUint(arr[idx], 10, 16); err != nil { 249 d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 250 return 251 } 252 v.SetUint(u64) 253 set = true 254 255 case reflect.Uint32: 256 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 257 return 258 } 259 var u64 uint64 260 if u64, err = strconv.ParseUint(arr[idx], 10, 32); err != nil { 261 d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 262 return 263 } 264 v.SetUint(u64) 265 set = true 266 267 case reflect.Int, reflect.Int64: 268 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 269 return 270 } 271 var i64 int64 272 if i64, err = strconv.ParseInt(arr[idx], 10, 64); err != nil { 273 d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 274 return 275 } 276 v.SetInt(i64) 277 set = true 278 279 case reflect.Int8: 280 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 281 return 282 } 283 var i64 int64 284 if i64, err = strconv.ParseInt(arr[idx], 10, 8); err != nil { 285 d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 286 return 287 } 288 v.SetInt(i64) 289 set = true 290 291 case reflect.Int16: 292 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 293 return 294 } 295 var i64 int64 296 if i64, err = strconv.ParseInt(arr[idx], 10, 16); err != nil { 297 d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 298 return 299 } 300 v.SetInt(i64) 301 set = true 302 303 case reflect.Int32: 304 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 305 return 306 } 307 var i64 int64 308 if i64, err = strconv.ParseInt(arr[idx], 10, 32); err != nil { 309 d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 310 return 311 } 312 v.SetInt(i64) 313 set = true 314 315 case reflect.Float32: 316 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 317 return 318 } 319 var f float64 320 if f, err = strconv.ParseFloat(arr[idx], 32); err != nil { 321 d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 322 return 323 } 324 v.SetFloat(f) 325 set = true 326 327 case reflect.Float64: 328 if !ok || idx == len(arr) || len(arr[idx]) == 0 { 329 return 330 } 331 var f float64 332 if f, err = strconv.ParseFloat(arr[idx], 64); err != nil { 333 d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 334 return 335 } 336 v.SetFloat(f) 337 set = true 338 339 case reflect.Bool: 340 if !ok || idx == len(arr) { 341 return 342 } 343 var b bool 344 if b, err = parseBool(arr[idx]); err != nil { 345 d.setError(namespace, fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace))) 346 return 347 } 348 v.SetBool(b) 349 set = true 350 351 case reflect.Slice: 352 d.parseMapData() 353 // slice elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"} 354 355 if ok && len(arr) > 0 { 356 var varr reflect.Value 357 358 var ol int 359 l := len(arr) 360 361 if v.IsNil() { 362 varr = reflect.MakeSlice(v.Type(), len(arr), len(arr)) 363 } else { 364 365 ol = v.Len() 366 l += ol 367 368 if v.Cap() <= l { 369 varr = reflect.MakeSlice(v.Type(), l, l) 370 } else { 371 // preserve predefined capacity, possibly for reuse after decoding 372 varr = reflect.MakeSlice(v.Type(), l, v.Cap()) 373 } 374 reflect.Copy(varr, v) 375 } 376 377 for i := ol; i < l; i++ { 378 newVal := reflect.New(v.Type().Elem()).Elem() 379 380 if d.setFieldByType(newVal, namespace, i-ol) { 381 set = true 382 varr.Index(i).Set(newVal) 383 } 384 } 385 386 v.Set(varr) 387 } 388 389 // maybe it's an numbered array i.e. Phone[0].Number 390 if rd := d.findAlias(string(namespace)); rd != nil { 391 392 var varr reflect.Value 393 var kv key 394 395 sl := rd.sliceLen + 1 396 397 // checking below for maxArraySize, but if array exists and already 398 // has sufficient capacity allocated then we do not check as the code 399 // obviously allows a capacity greater than the maxArraySize. 400 401 if v.IsNil() { 402 403 if sl > d.d.maxArraySize { 404 d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize)) 405 return 406 } 407 408 varr = reflect.MakeSlice(v.Type(), sl, sl) 409 410 } else if v.Len() < sl { 411 412 if v.Cap() <= sl { 413 414 if sl > d.d.maxArraySize { 415 d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize)) 416 return 417 } 418 419 varr = reflect.MakeSlice(v.Type(), sl, sl) 420 } else { 421 varr = reflect.MakeSlice(v.Type(), sl, v.Cap()) 422 } 423 424 reflect.Copy(varr, v) 425 426 } else { 427 varr = v 428 } 429 430 for i := 0; i < len(rd.keys); i++ { 431 432 kv = rd.keys[i] 433 newVal := reflect.New(varr.Type().Elem()).Elem() 434 435 if kv.ivalue == -1 { 436 d.setError(namespace, fmt.Errorf("invalid slice index '%s'", kv.value)) 437 continue 438 } 439 440 if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) { 441 set = true 442 varr.Index(kv.ivalue).Set(newVal) 443 } 444 } 445 446 if !set { 447 return 448 } 449 450 v.Set(varr) 451 } 452 453 case reflect.Array: 454 d.parseMapData() 455 456 // array elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"} 457 458 if ok && len(arr) > 0 { 459 var varr reflect.Value 460 l := len(arr) 461 overCapacity := v.Len() < l 462 if overCapacity { 463 // more values than array capacity, ignore values over capacity as it's possible some would just want 464 // to grab the first x number of elements; in the future strict mode logic should return an error 465 fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values") 466 } 467 varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem()))) 468 reflect.Copy(varr, v) 469 470 if v.Len() < len(arr) { 471 l = v.Len() 472 } 473 for i := 0; i < l; i++ { 474 newVal := reflect.New(v.Type().Elem()).Elem() 475 476 if d.setFieldByType(newVal, namespace, i) { 477 set = true 478 varr.Index(i).Set(newVal) 479 } 480 } 481 v.Set(varr) 482 } 483 484 // maybe it's an numbered array i.e. Phone[0].Number 485 if rd := d.findAlias(string(namespace)); rd != nil { 486 var varr reflect.Value 487 var kv key 488 489 overCapacity := rd.sliceLen >= v.Len() 490 if overCapacity { 491 // more values than array capacity, ignore values over capacity as it's possible some would just want 492 // to grab the first x number of elements; in the future strict mode logic should return an error 493 fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values") 494 } 495 varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem()))) 496 reflect.Copy(varr, v) 497 498 for i := 0; i < len(rd.keys); i++ { 499 kv = rd.keys[i] 500 if kv.ivalue >= v.Len() { 501 continue 502 } 503 newVal := reflect.New(varr.Type().Elem()).Elem() 504 505 if kv.ivalue == -1 { 506 d.setError(namespace, fmt.Errorf("invalid array index '%s'", kv.value)) 507 continue 508 } 509 510 if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) { 511 set = true 512 varr.Index(kv.ivalue).Set(newVal) 513 } 514 } 515 516 if !set { 517 return 518 } 519 v.Set(varr) 520 } 521 522 case reflect.Map: 523 var rd *recursiveData 524 525 d.parseMapData() 526 527 // no natural map support so skip directly to dm lookup 528 if rd = d.findAlias(string(namespace)); rd == nil { 529 return 530 } 531 532 var existing bool 533 var kv key 534 var mp reflect.Value 535 var mk reflect.Value 536 537 typ := v.Type() 538 539 if v.IsNil() { 540 mp = reflect.MakeMap(typ) 541 } else { 542 existing = true 543 mp = v 544 } 545 546 for i := 0; i < len(rd.keys); i++ { 547 newVal := reflect.New(typ.Elem()).Elem() 548 mk = reflect.New(typ.Key()).Elem() 549 kv = rd.keys[i] 550 551 if err := d.getMapKey(kv.value, mk, namespace); err != nil { 552 d.setError(namespace, err) 553 continue 554 } 555 556 if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) { 557 set = true 558 mp.SetMapIndex(mk, newVal) 559 } 560 } 561 562 if !set || existing { 563 return 564 } 565 566 v.Set(mp) 567 568 case reflect.Struct: 569 typ := v.Type() 570 571 // if we get here then no custom time function declared so use RFC3339 by default 572 if typ == timeType { 573 574 if !ok || len(arr[idx]) == 0 { 575 return 576 } 577 578 t, err := time.Parse(time.RFC3339, arr[idx]) 579 if err != nil { 580 d.setError(namespace, err) 581 } 582 583 v.Set(reflect.ValueOf(t)) 584 set = true 585 return 586 } 587 588 d.parseMapData() 589 590 // we must be recursing infinitly...but that's ok we caught it on the very first overun. 591 if len(namespace) > d.maxKeyLen { 592 return 593 } 594 595 set = d.traverseStruct(v, typ, namespace) 596 } 597 return 598 } 599 600 func (d *decoder) getMapKey(key string, current reflect.Value, namespace []byte) (err error) { 601 602 v, kind := ExtractType(current) 603 604 if d.d.customTypeFuncs != nil { 605 if cf, ok := d.d.customTypeFuncs[v.Type()]; ok { 606 607 val, er := cf([]string{key}) 608 if er != nil { 609 err = er 610 return 611 } 612 613 v.Set(reflect.ValueOf(val)) 614 return 615 } 616 } 617 618 switch kind { 619 case reflect.Interface: 620 // If interface would have been set on the struct before decoding, 621 // say to a struct value we would not get here but kind would be struct. 622 v.Set(reflect.ValueOf(key)) 623 return 624 case reflect.Ptr: 625 newVal := reflect.New(v.Type().Elem()) 626 if err = d.getMapKey(key, newVal.Elem(), namespace); err == nil { 627 v.Set(newVal) 628 } 629 630 case reflect.String: 631 v.SetString(key) 632 633 case reflect.Uint, reflect.Uint64: 634 635 u64, e := strconv.ParseUint(key, 10, 64) 636 if e != nil { 637 err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 638 return 639 } 640 641 v.SetUint(u64) 642 643 case reflect.Uint8: 644 645 u64, e := strconv.ParseUint(key, 10, 8) 646 if e != nil { 647 err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 648 return 649 } 650 651 v.SetUint(u64) 652 653 case reflect.Uint16: 654 655 u64, e := strconv.ParseUint(key, 10, 16) 656 if e != nil { 657 err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 658 return 659 } 660 661 v.SetUint(u64) 662 663 case reflect.Uint32: 664 665 u64, e := strconv.ParseUint(key, 10, 32) 666 if e != nil { 667 err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 668 return 669 } 670 671 v.SetUint(u64) 672 673 case reflect.Int, reflect.Int64: 674 675 i64, e := strconv.ParseInt(key, 10, 64) 676 if e != nil { 677 err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 678 return 679 } 680 681 v.SetInt(i64) 682 683 case reflect.Int8: 684 685 i64, e := strconv.ParseInt(key, 10, 8) 686 if e != nil { 687 err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 688 return 689 } 690 691 v.SetInt(i64) 692 693 case reflect.Int16: 694 695 i64, e := strconv.ParseInt(key, 10, 16) 696 if e != nil { 697 err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 698 return 699 } 700 701 v.SetInt(i64) 702 703 case reflect.Int32: 704 705 i64, e := strconv.ParseInt(key, 10, 32) 706 if e != nil { 707 err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 708 return 709 } 710 711 v.SetInt(i64) 712 713 case reflect.Float32: 714 715 f, e := strconv.ParseFloat(key, 32) 716 if e != nil { 717 err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 718 return 719 } 720 721 v.SetFloat(f) 722 723 case reflect.Float64: 724 725 f, e := strconv.ParseFloat(key, 64) 726 if e != nil { 727 err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 728 return 729 } 730 731 v.SetFloat(f) 732 733 case reflect.Bool: 734 735 b, e := parseBool(key) 736 if e != nil { 737 err = fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 738 return 739 } 740 741 v.SetBool(b) 742 743 default: 744 err = fmt.Errorf("Unsupported Map Key '%s', Type '%v' Namespace '%s'", key, v.Type(), string(namespace)) 745 } 746 747 return 748 }