1
2
3
4
5
6
7
8
9
10 package asn1
11
12
13
14
15
16
17
18
19
20
21
22 import (
23 "errors"
24 "fmt"
25 "math"
26 "math/big"
27 "reflect"
28 "strconv"
29 "time"
30 "unicode/utf8"
31 )
32
33
34
35 type StructuralError struct {
36 Msg string
37 }
38
39 func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
40
41
42 type SyntaxError struct {
43 Msg string
44 }
45
46 func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
47
48
49
50
51
52 func parseBool(bytes []byte) (ret bool, err error) {
53 if len(bytes) != 1 {
54 err = SyntaxError{"invalid boolean"}
55 return
56 }
57
58
59
60
61 switch bytes[0] {
62 case 0:
63 ret = false
64 case 0xff:
65 ret = true
66 default:
67 err = SyntaxError{"invalid boolean"}
68 }
69
70 return
71 }
72
73
74
75
76
77 func checkInteger(bytes []byte) error {
78 if len(bytes) == 0 {
79 return StructuralError{"empty integer"}
80 }
81 if len(bytes) == 1 {
82 return nil
83 }
84 if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
85 return StructuralError{"integer not minimally-encoded"}
86 }
87 return nil
88 }
89
90
91
92 func parseInt64(bytes []byte) (ret int64, err error) {
93 err = checkInteger(bytes)
94 if err != nil {
95 return
96 }
97 if len(bytes) > 8 {
98
99 err = StructuralError{"integer too large"}
100 return
101 }
102 for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
103 ret <<= 8
104 ret |= int64(bytes[bytesRead])
105 }
106
107
108 ret <<= 64 - uint8(len(bytes))*8
109 ret >>= 64 - uint8(len(bytes))*8
110 return
111 }
112
113
114
115 func parseInt32(bytes []byte) (int32, error) {
116 if err := checkInteger(bytes); err != nil {
117 return 0, err
118 }
119 ret64, err := parseInt64(bytes)
120 if err != nil {
121 return 0, err
122 }
123 if ret64 != int64(int32(ret64)) {
124 return 0, StructuralError{"integer too large"}
125 }
126 return int32(ret64), nil
127 }
128
129 var bigOne = big.NewInt(1)
130
131
132
133 func parseBigInt(bytes []byte) (*big.Int, error) {
134 if err := checkInteger(bytes); err != nil {
135 return nil, err
136 }
137 ret := new(big.Int)
138 if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
139
140 notBytes := make([]byte, len(bytes))
141 for i := range notBytes {
142 notBytes[i] = ^bytes[i]
143 }
144 ret.SetBytes(notBytes)
145 ret.Add(ret, bigOne)
146 ret.Neg(ret)
147 return ret, nil
148 }
149 ret.SetBytes(bytes)
150 return ret, nil
151 }
152
153
154
155
156
157
158 type BitString struct {
159 Bytes []byte
160 BitLength int
161 }
162
163
164
165 func (b BitString) At(i int) int {
166 if i < 0 || i >= b.BitLength {
167 return 0
168 }
169 x := i / 8
170 y := 7 - uint(i%8)
171 return int(b.Bytes[x]>>y) & 1
172 }
173
174
175
176 func (b BitString) RightAlign() []byte {
177 shift := uint(8 - (b.BitLength % 8))
178 if shift == 8 || len(b.Bytes) == 0 {
179 return b.Bytes
180 }
181
182 a := make([]byte, len(b.Bytes))
183 a[0] = b.Bytes[0] >> shift
184 for i := 1; i < len(b.Bytes); i++ {
185 a[i] = b.Bytes[i-1] << (8 - shift)
186 a[i] |= b.Bytes[i] >> shift
187 }
188
189 return a
190 }
191
192
193 func parseBitString(bytes []byte) (ret BitString, err error) {
194 if len(bytes) == 0 {
195 err = SyntaxError{"zero length BIT STRING"}
196 return
197 }
198 paddingBits := int(bytes[0])
199 if paddingBits > 7 ||
200 len(bytes) == 1 && paddingBits > 0 ||
201 bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
202 err = SyntaxError{"invalid padding bits in BIT STRING"}
203 return
204 }
205 ret.BitLength = (len(bytes)-1)*8 - paddingBits
206 ret.Bytes = bytes[1:]
207 return
208 }
209
210
211
212
213 var NullRawValue = RawValue{Tag: TagNull}
214
215
216 var NullBytes = []byte{TagNull, 0}
217
218
219
220
221 type ObjectIdentifier []int
222
223
224 func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
225 if len(oi) != len(other) {
226 return false
227 }
228 for i := 0; i < len(oi); i++ {
229 if oi[i] != other[i] {
230 return false
231 }
232 }
233
234 return true
235 }
236
237 func (oi ObjectIdentifier) String() string {
238 var s string
239
240 for i, v := range oi {
241 if i > 0 {
242 s += "."
243 }
244 s += strconv.Itoa(v)
245 }
246
247 return s
248 }
249
250
251
252
253 func parseObjectIdentifier(bytes []byte) (s []int, err error) {
254 if len(bytes) == 0 {
255 err = SyntaxError{"zero length OBJECT IDENTIFIER"}
256 return
257 }
258
259
260
261 s = make([]int, len(bytes)+1)
262
263
264
265
266
267 v, offset, err := parseBase128Int(bytes, 0)
268 if err != nil {
269 return
270 }
271 if v < 80 {
272 s[0] = v / 40
273 s[1] = v % 40
274 } else {
275 s[0] = 2
276 s[1] = v - 80
277 }
278
279 i := 2
280 for ; offset < len(bytes); i++ {
281 v, offset, err = parseBase128Int(bytes, offset)
282 if err != nil {
283 return
284 }
285 s[i] = v
286 }
287 s = s[0:i]
288 return
289 }
290
291
292
293
294 type Enumerated int
295
296
297
298
299 type Flag bool
300
301
302
303 func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
304 offset = initOffset
305 var ret64 int64
306 for shifted := 0; offset < len(bytes); shifted++ {
307
308
309 if shifted == 5 {
310 err = StructuralError{"base 128 integer too large"}
311 return
312 }
313 ret64 <<= 7
314 b := bytes[offset]
315 ret64 |= int64(b & 0x7f)
316 offset++
317 if b&0x80 == 0 {
318 ret = int(ret64)
319
320 if ret64 > math.MaxInt32 {
321 err = StructuralError{"base 128 integer too large"}
322 }
323 return
324 }
325 }
326 err = SyntaxError{"truncated base 128 integer"}
327 return
328 }
329
330
331
332 func parseUTCTime(bytes []byte) (ret time.Time, err error) {
333 s := string(bytes)
334
335 formatStr := "0601021504Z0700"
336 ret, err = time.Parse(formatStr, s)
337 if err != nil {
338 formatStr = "060102150405Z0700"
339 ret, err = time.Parse(formatStr, s)
340 }
341 if err != nil {
342 return
343 }
344
345 if serialized := ret.Format(formatStr); serialized != s {
346 err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
347 return
348 }
349
350 if ret.Year() >= 2050 {
351
352 ret = ret.AddDate(-100, 0, 0)
353 }
354
355 return
356 }
357
358
359
360 func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
361 const formatStr = "20060102150405Z0700"
362 s := string(bytes)
363
364 if ret, err = time.Parse(formatStr, s); err != nil {
365 return
366 }
367
368 if serialized := ret.Format(formatStr); serialized != s {
369 err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
370 }
371
372 return
373 }
374
375
376
377
378
379 func parseNumericString(bytes []byte) (ret string, err error) {
380 for _, b := range bytes {
381 if !isNumeric(b) {
382 return "", SyntaxError{"NumericString contains invalid character"}
383 }
384 }
385 return string(bytes), nil
386 }
387
388
389 func isNumeric(b byte) bool {
390 return '0' <= b && b <= '9' ||
391 b == ' '
392 }
393
394
395
396
397
398 func parsePrintableString(bytes []byte) (ret string, err error) {
399 for _, b := range bytes {
400 if !isPrintable(b, allowAsterisk, allowAmpersand) {
401 err = SyntaxError{"PrintableString contains invalid character"}
402 return
403 }
404 }
405 ret = string(bytes)
406 return
407 }
408
409 type asteriskFlag bool
410 type ampersandFlag bool
411
412 const (
413 allowAsterisk asteriskFlag = true
414 rejectAsterisk asteriskFlag = false
415
416 allowAmpersand ampersandFlag = true
417 rejectAmpersand ampersandFlag = false
418 )
419
420
421
422
423 func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
424 return 'a' <= b && b <= 'z' ||
425 'A' <= b && b <= 'Z' ||
426 '0' <= b && b <= '9' ||
427 '\'' <= b && b <= ')' ||
428 '+' <= b && b <= '/' ||
429 b == ' ' ||
430 b == ':' ||
431 b == '=' ||
432 b == '?' ||
433
434
435
436 (bool(asterisk) && b == '*') ||
437
438
439
440
441 (bool(ampersand) && b == '&')
442 }
443
444
445
446
447
448 func parseIA5String(bytes []byte) (ret string, err error) {
449 for _, b := range bytes {
450 if b >= utf8.RuneSelf {
451 err = SyntaxError{"IA5String contains invalid character"}
452 return
453 }
454 }
455 ret = string(bytes)
456 return
457 }
458
459
460
461
462
463 func parseT61String(bytes []byte) (ret string, err error) {
464 return string(bytes), nil
465 }
466
467
468
469
470
471 func parseUTF8String(bytes []byte) (ret string, err error) {
472 if !utf8.Valid(bytes) {
473 return "", errors.New("asn1: invalid UTF-8 string")
474 }
475 return string(bytes), nil
476 }
477
478
479 type RawValue struct {
480 Class, Tag int
481 IsCompound bool
482 Bytes []byte
483 FullBytes []byte
484 }
485
486
487
488
489 type RawContent []byte
490
491
492
493
494
495
496
497 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
498 offset = initOffset
499
500
501 if offset >= len(bytes) {
502 err = errors.New("asn1: internal error in parseTagAndLength")
503 return
504 }
505 b := bytes[offset]
506 offset++
507 ret.class = int(b >> 6)
508 ret.isCompound = b&0x20 == 0x20
509 ret.tag = int(b & 0x1f)
510
511
512
513 if ret.tag == 0x1f {
514 ret.tag, offset, err = parseBase128Int(bytes, offset)
515 if err != nil {
516 return
517 }
518
519 if ret.tag < 0x1f {
520 err = SyntaxError{"non-minimal tag"}
521 return
522 }
523 }
524 if offset >= len(bytes) {
525 err = SyntaxError{"truncated tag or length"}
526 return
527 }
528 b = bytes[offset]
529 offset++
530 if b&0x80 == 0 {
531
532 ret.length = int(b & 0x7f)
533 } else {
534
535 numBytes := int(b & 0x7f)
536 if numBytes == 0 {
537 err = SyntaxError{"indefinite length found (not DER)"}
538 return
539 }
540 ret.length = 0
541 for i := 0; i < numBytes; i++ {
542 if offset >= len(bytes) {
543 err = SyntaxError{"truncated tag or length"}
544 return
545 }
546 b = bytes[offset]
547 offset++
548 if ret.length >= 1<<23 {
549
550
551 err = StructuralError{"length too large"}
552 return
553 }
554 ret.length <<= 8
555 ret.length |= int(b)
556 if ret.length == 0 {
557
558 err = StructuralError{"superfluous leading zeros in length"}
559 return
560 }
561 }
562
563 if ret.length < 0x80 {
564 err = StructuralError{"non-minimal length"}
565 return
566 }
567 }
568
569 return
570 }
571
572
573
574
575 func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
576 matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
577 if !ok {
578 err = StructuralError{"unknown Go type for slice"}
579 return
580 }
581
582
583
584 numElements := 0
585 for offset := 0; offset < len(bytes); {
586 var t tagAndLength
587 t, offset, err = parseTagAndLength(bytes, offset)
588 if err != nil {
589 return
590 }
591 switch t.tag {
592 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString:
593
594
595
596 t.tag = TagPrintableString
597 case TagGeneralizedTime, TagUTCTime:
598
599 t.tag = TagUTCTime
600 }
601
602 if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
603 err = StructuralError{"sequence tag mismatch"}
604 return
605 }
606 if invalidLength(offset, t.length, len(bytes)) {
607 err = SyntaxError{"truncated sequence"}
608 return
609 }
610 offset += t.length
611 numElements++
612 }
613 ret = reflect.MakeSlice(sliceType, numElements, numElements)
614 params := fieldParameters{}
615 offset := 0
616 for i := 0; i < numElements; i++ {
617 offset, err = parseField(ret.Index(i), bytes, offset, params)
618 if err != nil {
619 return
620 }
621 }
622 return
623 }
624
625 var (
626 bitStringType = reflect.TypeOf(BitString{})
627 objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
628 enumeratedType = reflect.TypeOf(Enumerated(0))
629 flagType = reflect.TypeOf(Flag(false))
630 timeType = reflect.TypeOf(time.Time{})
631 rawValueType = reflect.TypeOf(RawValue{})
632 rawContentsType = reflect.TypeOf(RawContent(nil))
633 bigIntType = reflect.TypeOf(new(big.Int))
634 )
635
636
637
638 func invalidLength(offset, length, sliceLength int) bool {
639 return offset+length < offset || offset+length > sliceLength
640 }
641
642
643
644
645 func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
646 offset = initOffset
647 fieldType := v.Type()
648
649
650 if offset == len(bytes) {
651 if !setDefaultValue(v, params) {
652 err = SyntaxError{"sequence truncated"}
653 }
654 return
655 }
656
657
658 if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
659 var t tagAndLength
660 t, offset, err = parseTagAndLength(bytes, offset)
661 if err != nil {
662 return
663 }
664 if invalidLength(offset, t.length, len(bytes)) {
665 err = SyntaxError{"data truncated"}
666 return
667 }
668 var result interface{}
669 if !t.isCompound && t.class == ClassUniversal {
670 innerBytes := bytes[offset : offset+t.length]
671 switch t.tag {
672 case TagPrintableString:
673 result, err = parsePrintableString(innerBytes)
674 case TagNumericString:
675 result, err = parseNumericString(innerBytes)
676 case TagIA5String:
677 result, err = parseIA5String(innerBytes)
678 case TagT61String:
679 result, err = parseT61String(innerBytes)
680 case TagUTF8String:
681 result, err = parseUTF8String(innerBytes)
682 case TagInteger:
683 result, err = parseInt64(innerBytes)
684 case TagBitString:
685 result, err = parseBitString(innerBytes)
686 case TagOID:
687 result, err = parseObjectIdentifier(innerBytes)
688 case TagUTCTime:
689 result, err = parseUTCTime(innerBytes)
690 case TagGeneralizedTime:
691 result, err = parseGeneralizedTime(innerBytes)
692 case TagOctetString:
693 result = innerBytes
694 default:
695
696 }
697 }
698 offset += t.length
699 if err != nil {
700 return
701 }
702 if result != nil {
703 v.Set(reflect.ValueOf(result))
704 }
705 return
706 }
707
708 t, offset, err := parseTagAndLength(bytes, offset)
709 if err != nil {
710 return
711 }
712 if params.explicit {
713 expectedClass := ClassContextSpecific
714 if params.application {
715 expectedClass = ClassApplication
716 }
717 if offset == len(bytes) {
718 err = StructuralError{"explicit tag has no child"}
719 return
720 }
721 if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
722 if fieldType == rawValueType {
723
724 } else if t.length > 0 {
725 t, offset, err = parseTagAndLength(bytes, offset)
726 if err != nil {
727 return
728 }
729 } else {
730 if fieldType != flagType {
731 err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
732 return
733 }
734 v.SetBool(true)
735 return
736 }
737 } else {
738
739 ok := setDefaultValue(v, params)
740 if ok {
741 offset = initOffset
742 } else {
743 err = StructuralError{"explicitly tagged member didn't match"}
744 }
745 return
746 }
747 }
748
749 matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
750 if !ok1 {
751 err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
752 return
753 }
754
755
756
757
758
759 if universalTag == TagPrintableString {
760 if t.class == ClassUniversal {
761 switch t.tag {
762 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString:
763 universalTag = t.tag
764 }
765 } else if params.stringType != 0 {
766 universalTag = params.stringType
767 }
768 }
769
770
771
772 if universalTag == TagUTCTime && t.tag == TagGeneralizedTime && t.class == ClassUniversal {
773 universalTag = TagGeneralizedTime
774 }
775
776 if params.set {
777 universalTag = TagSet
778 }
779
780 matchAnyClassAndTag := matchAny
781 expectedClass := ClassUniversal
782 expectedTag := universalTag
783
784 if !params.explicit && params.tag != nil {
785 expectedClass = ClassContextSpecific
786 expectedTag = *params.tag
787 matchAnyClassAndTag = false
788 }
789
790 if !params.explicit && params.application && params.tag != nil {
791 expectedClass = ClassApplication
792 expectedTag = *params.tag
793 matchAnyClassAndTag = false
794 }
795
796
797 if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
798 (!matchAny && t.isCompound != compoundType) {
799
800 ok := setDefaultValue(v, params)
801 if ok {
802 offset = initOffset
803 } else {
804 err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
805 }
806 return
807 }
808 if invalidLength(offset, t.length, len(bytes)) {
809 err = SyntaxError{"data truncated"}
810 return
811 }
812 innerBytes := bytes[offset : offset+t.length]
813 offset += t.length
814
815
816 switch fieldType {
817 case rawValueType:
818 result := RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
819 v.Set(reflect.ValueOf(result))
820 return
821 case objectIdentifierType:
822 newSlice, err1 := parseObjectIdentifier(innerBytes)
823 v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
824 if err1 == nil {
825 reflect.Copy(v, reflect.ValueOf(newSlice))
826 }
827 err = err1
828 return
829 case bitStringType:
830 bs, err1 := parseBitString(innerBytes)
831 if err1 == nil {
832 v.Set(reflect.ValueOf(bs))
833 }
834 err = err1
835 return
836 case timeType:
837 var time time.Time
838 var err1 error
839 if universalTag == TagUTCTime {
840 time, err1 = parseUTCTime(innerBytes)
841 } else {
842 time, err1 = parseGeneralizedTime(innerBytes)
843 }
844 if err1 == nil {
845 v.Set(reflect.ValueOf(time))
846 }
847 err = err1
848 return
849 case enumeratedType:
850 parsedInt, err1 := parseInt32(innerBytes)
851 if err1 == nil {
852 v.SetInt(int64(parsedInt))
853 }
854 err = err1
855 return
856 case flagType:
857 v.SetBool(true)
858 return
859 case bigIntType:
860 parsedInt, err1 := parseBigInt(innerBytes)
861 if err1 == nil {
862 v.Set(reflect.ValueOf(parsedInt))
863 }
864 err = err1
865 return
866 }
867 switch val := v; val.Kind() {
868 case reflect.Bool:
869 parsedBool, err1 := parseBool(innerBytes)
870 if err1 == nil {
871 val.SetBool(parsedBool)
872 }
873 err = err1
874 return
875 case reflect.Int, reflect.Int32, reflect.Int64:
876 if val.Type().Size() == 4 {
877 parsedInt, err1 := parseInt32(innerBytes)
878 if err1 == nil {
879 val.SetInt(int64(parsedInt))
880 }
881 err = err1
882 } else {
883 parsedInt, err1 := parseInt64(innerBytes)
884 if err1 == nil {
885 val.SetInt(parsedInt)
886 }
887 err = err1
888 }
889 return
890
891 case reflect.Struct:
892 structType := fieldType
893
894 for i := 0; i < structType.NumField(); i++ {
895 if structType.Field(i).PkgPath != "" {
896 err = StructuralError{"struct contains unexported fields"}
897 return
898 }
899 }
900
901 if structType.NumField() > 0 &&
902 structType.Field(0).Type == rawContentsType {
903 bytes := bytes[initOffset:offset]
904 val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
905 }
906
907 innerOffset := 0
908 for i := 0; i < structType.NumField(); i++ {
909 field := structType.Field(i)
910 if i == 0 && field.Type == rawContentsType {
911 continue
912 }
913 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
914 if err != nil {
915 return
916 }
917 }
918
919
920
921 return
922 case reflect.Slice:
923 sliceType := fieldType
924 if sliceType.Elem().Kind() == reflect.Uint8 {
925 val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
926 reflect.Copy(val, reflect.ValueOf(innerBytes))
927 return
928 }
929 newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
930 if err1 == nil {
931 val.Set(newSlice)
932 }
933 err = err1
934 return
935 case reflect.String:
936 var v string
937 switch universalTag {
938 case TagPrintableString:
939 v, err = parsePrintableString(innerBytes)
940 case TagNumericString:
941 v, err = parseNumericString(innerBytes)
942 case TagIA5String:
943 v, err = parseIA5String(innerBytes)
944 case TagT61String:
945 v, err = parseT61String(innerBytes)
946 case TagUTF8String:
947 v, err = parseUTF8String(innerBytes)
948 case TagGeneralString:
949
950
951
952
953 v, err = parseT61String(innerBytes)
954 default:
955 err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
956 }
957 if err == nil {
958 val.SetString(v)
959 }
960 return
961 }
962 err = StructuralError{"unsupported: " + v.Type().String()}
963 return
964 }
965
966
967
968 func canHaveDefaultValue(k reflect.Kind) bool {
969 switch k {
970 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
971 return true
972 }
973
974 return false
975 }
976
977
978
979
980 func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
981 if !params.optional {
982 return
983 }
984 ok = true
985 if params.defaultValue == nil {
986 return
987 }
988 if canHaveDefaultValue(v.Kind()) {
989 v.SetInt(*params.defaultValue)
990 }
991 return
992 }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
1047 return UnmarshalWithParams(b, val, "")
1048 }
1049
1050
1051
1052 func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) {
1053 v := reflect.ValueOf(val).Elem()
1054 offset, err := parseField(v, b, 0, parseFieldParameters(params))
1055 if err != nil {
1056 return nil, err
1057 }
1058 return b[offset:], nil
1059 }
1060
View as plain text