1// Package ogórek is a library for decoding Python's pickle format. 2// 3// ogórek is Polish for "pickle". 4package ogórek 5 6import ( 7 "bufio" 8 "bytes" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "io" 13 "math" 14 "math/big" 15 "reflect" 16 "strconv" 17) 18 19// Opcodes 20const ( 21 opMark byte = '(' // push special markobject on stack 22 opStop = '.' // every pickle ends with STOP 23 opPop = '0' // discard topmost stack item 24 opPopMark = '1' // discard stack top through topmost markobject 25 opDup = '2' // duplicate top stack item 26 opFloat = 'F' // push float object; decimal string argument 27 opInt = 'I' // push integer or bool; decimal string argument 28 opBinint = 'J' // push four-byte signed int 29 opBinint1 = 'K' // push 1-byte unsigned int 30 opLong = 'L' // push long; decimal string argument 31 opBinint2 = 'M' // push 2-byte unsigned int 32 opNone = 'N' // push None 33 opPersid = 'P' // push persistent object; id is taken from string arg 34 opBinpersid = 'Q' // " " " ; " " " " stack 35 opReduce = 'R' // apply callable to argtuple, both on stack 36 opString = 'S' // push string; NL-terminated string argument 37 opBinstring = 'T' // push string; counted binary string argument 38 opShortBinstring = 'U' // " " ; " " " " < 256 bytes 39 opUnicode = 'V' // push Unicode string; raw-unicode-escaped"d argument 40 opBinunicode = 'X' // " " " ; counted UTF-8 string argument 41 opAppend = 'a' // append stack top to list below it 42 opBuild = 'b' // call __setstate__ or __dict__.update() 43 opGlobal = 'c' // push self.find_class(modname, name); 2 string args 44 opDict = 'd' // build a dict from stack items 45 opEmptyDict = '}' // push empty dict 46 opAppends = 'e' // extend list on stack by topmost stack slice 47 opGet = 'g' // push item from memo on stack; index is string arg 48 opBinget = 'h' // " " " " " " ; " " 1-byte arg 49 opInst = 'i' // build & push class instance 50 opLongBinget = 'j' // push item from memo on stack; index is 4-byte arg 51 opList = 'l' // build list from topmost stack items 52 opEmptyList = ']' // push empty list 53 opObj = 'o' // build & push class instance 54 opPut = 'p' // store stack top in memo; index is string arg 55 opBinput = 'q' // " " " " " ; " " 1-byte arg 56 opLongBinput = 'r' // " " " " " ; " " 4-byte arg 57 opSetitem = 's' // add key+value pair to dict 58 opTuple = 't' // build tuple from topmost stack items 59 opEmptyTuple = ')' // push empty tuple 60 opSetitems = 'u' // modify dict by adding topmost key+value pairs 61 opBinfloat = 'G' // push float; arg is 8-byte float encoding 62 63 opTrue = "I01\n" // not an opcode; see INT docs in pickletools.py 64 opFalse = "I00\n" // not an opcode; see INT docs in pickletools.py 65 66 // Protocol 2 67 68 opProto = '\x80' // identify pickle protocol 69 opNewobj = '\x81' // build object by applying cls.__new__ to argtuple 70 opExt1 = '\x82' // push object from extension registry; 1-byte index 71 opExt2 = '\x83' // ditto, but 2-byte index 72 opExt4 = '\x84' // ditto, but 4-byte index 73 opTuple1 = '\x85' // build 1-tuple from stack top 74 opTuple2 = '\x86' // build 2-tuple from two topmost stack items 75 opTuple3 = '\x87' // build 3-tuple from three topmost stack items 76 opNewtrue = '\x88' // push True 77 opNewfalse = '\x89' // push False 78 opLong1 = '\x8a' // push long from < 256 bytes 79 opLong4 = '\x8b' // push really big long 80 81 // Protocol 4 82 opShortBinUnicode = '\x8c' // push short string; UTF-8 length < 256 bytes 83 opMemoize = '\x94' // store top of the stack in memo 84 opFrame = '\x95' // indicate the beginning of a new frame 85) 86 87var errNotImplemented = errors.New("unimplemented opcode") 88var ErrInvalidPickleVersion = errors.New("invalid pickle version") 89var errNoMarker = errors.New("no marker in stack") 90var errStackUnderflow = errors.New("pickle: stack underflow") 91 92type OpcodeError struct { 93 Key byte 94 Pos int 95} 96 97func (e OpcodeError) Error() string { 98 return fmt.Sprintf("Unknown opcode %d (%c) at position %d: %q", e.Key, e.Key, e.Pos, e.Key) 99} 100 101// special marker 102type mark struct{} 103 104// None is a representation of Python's None. 105type None struct{} 106 107// Tuple is a representation of Python's tuple. 108type Tuple []interface{} 109 110// Decoder is a decoder for pickle streams. 111type Decoder struct { 112 r *bufio.Reader 113 stack []interface{} 114 memo map[string]interface{} 115 116 // a reusable buffer that can be used by the various decoding functions 117 // functions using this should call buf.Reset to clear the old contents 118 buf bytes.Buffer 119 120 // reusable buffer for readLine 121 line []byte 122} 123 124// NewDecoder constructs a new Decoder which will decode the pickle stream in r. 125func NewDecoder(r io.Reader) *Decoder { 126 reader := bufio.NewReader(r) 127 return &Decoder{r: reader, stack: make([]interface{}, 0), memo: make(map[string]interface{})} 128} 129 130// Decode decodes the pickle stream and returns the result or an error. 131func (d *Decoder) Decode() (interface{}, error) { 132 133 insn := 0 134loop: 135 for { 136 key, err := d.r.ReadByte() 137 if err != nil { 138 if err == io.EOF && insn != 0 { 139 err = io.ErrUnexpectedEOF 140 } 141 return nil, err 142 } 143 144 insn++ 145 146 switch key { 147 case opMark: 148 d.mark() 149 case opStop: 150 break loop 151 case opPop: 152 _, err = d.pop() 153 case opPopMark: 154 d.popMark() 155 case opDup: 156 err = d.dup() 157 case opFloat: 158 err = d.loadFloat() 159 case opInt: 160 err = d.loadInt() 161 case opBinint: 162 err = d.loadBinInt() 163 case opBinint1: 164 err = d.loadBinInt1() 165 case opLong: 166 err = d.loadLong() 167 case opBinint2: 168 err = d.loadBinInt2() 169 case opNone: 170 err = d.loadNone() 171 case opPersid: 172 err = d.loadPersid() 173 case opBinpersid: 174 err = d.loadBinPersid() 175 case opReduce: 176 err = d.reduce() 177 case opString: 178 err = d.loadString() 179 case opBinstring: 180 err = d.loadBinString() 181 case opShortBinstring: 182 err = d.loadShortBinString() 183 case opUnicode: 184 err = d.loadUnicode() 185 case opBinunicode: 186 err = d.loadBinUnicode() 187 case opAppend: 188 err = d.loadAppend() 189 case opBuild: 190 err = d.build() 191 case opGlobal: 192 err = d.global() 193 case opDict: 194 err = d.loadDict() 195 case opEmptyDict: 196 err = d.loadEmptyDict() 197 case opAppends: 198 err = d.loadAppends() 199 case opGet: 200 err = d.get() 201 case opBinget: 202 err = d.binGet() 203 case opInst: 204 err = d.inst() 205 case opLong1: 206 err = d.loadLong1() 207 case opNewfalse: 208 err = d.loadBool(false) 209 case opNewtrue: 210 err = d.loadBool(true) 211 case opLongBinget: 212 err = d.longBinGet() 213 case opList: 214 err = d.loadList() 215 case opEmptyList: 216 d.push([]interface{}{}) 217 case opObj: 218 err = d.obj() 219 case opPut: 220 err = d.loadPut() 221 case opBinput: 222 err = d.binPut() 223 case opLongBinput: 224 err = d.longBinPut() 225 case opSetitem: 226 err = d.loadSetItem() 227 case opTuple: 228 err = d.loadTuple() 229 case opTuple1: 230 err = d.loadTuple1() 231 case opTuple2: 232 err = d.loadTuple2() 233 case opTuple3: 234 err = d.loadTuple3() 235 case opEmptyTuple: 236 d.push(Tuple{}) 237 case opSetitems: 238 err = d.loadSetItems() 239 case opBinfloat: 240 err = d.binFloat() 241 case opFrame: 242 err = d.loadFrame() 243 case opShortBinUnicode: 244 err = d.loadShortBinUnicode() 245 case opMemoize: 246 err = d.loadMemoize() 247 case opProto: 248 v, err := d.r.ReadByte() 249 if err == nil && v != 2 { 250 err = ErrInvalidPickleVersion 251 } 252 253 default: 254 return nil, OpcodeError{key, insn} 255 } 256 257 if err != nil { 258 if err == errNotImplemented { 259 return nil, OpcodeError{key, insn} 260 } 261 // EOF from individual opcode decoder is unexpected end of stream 262 if err == io.EOF { 263 err = io.ErrUnexpectedEOF 264 } 265 return nil, err 266 } 267 } 268 return d.pop() 269} 270 271// readLine reads next line from pickle stream 272// returned line is valid only till next call to readLine 273func (d *Decoder) readLine() ([]byte, error) { 274 var ( 275 data []byte 276 isPrefix = true 277 err error 278 ) 279 d.line = d.line[:0] 280 for isPrefix { 281 data, isPrefix, err = d.r.ReadLine() 282 if err != nil { 283 return d.line, err 284 } 285 d.line = append(d.line, data...) 286 } 287 return d.line, nil 288} 289 290// Push a marker 291func (d *Decoder) mark() { 292 d.push(mark{}) 293} 294 295// Return the position of the topmost marker 296func (d *Decoder) marker() (int, error) { 297 m := mark{} 298 for k := len(d.stack) - 1; k >= 0; k-- { 299 if d.stack[k] == m { 300 return k, nil 301 } 302 } 303 return 0, errNoMarker 304} 305 306// Append a new value 307func (d *Decoder) push(v interface{}) { 308 d.stack = append(d.stack, v) 309} 310 311// Pop a value 312// The returned error is errStackUnderflow if decoder stack is empty 313func (d *Decoder) pop() (interface{}, error) { 314 ln := len(d.stack) - 1 315 if ln < 0 { 316 return nil, errStackUnderflow 317 } 318 v := d.stack[ln] 319 d.stack = d.stack[:ln] 320 return v, nil 321} 322 323// Pop a value (when you know for sure decoder stack is not empty) 324func (d *Decoder) xpop() interface{} { 325 v, err := d.pop() 326 if err != nil { 327 panic(err) 328 } 329 return v 330} 331 332// Discard the stack through to the topmost marker 333func (d *Decoder) popMark() error { 334 return errNotImplemented 335} 336 337// Duplicate the top stack item 338func (d *Decoder) dup() error { 339 if len(d.stack) < 1 { 340 return errStackUnderflow 341 } 342 d.stack = append(d.stack, d.stack[len(d.stack)-1]) 343 return nil 344} 345 346// Push a float 347func (d *Decoder) loadFloat() error { 348 line, err := d.readLine() 349 if err != nil { 350 return err 351 } 352 v, err := strconv.ParseFloat(string(line), 64) 353 if err != nil { 354 return err 355 } 356 d.push(interface{}(v)) 357 return nil 358} 359 360// Push an int 361func (d *Decoder) loadInt() error { 362 line, err := d.readLine() 363 if err != nil { 364 return err 365 } 366 367 var val interface{} 368 369 switch string(line) { 370 case opFalse[1:3]: 371 val = false 372 case opTrue[1:3]: 373 val = true 374 default: 375 i, err := strconv.ParseInt(string(line), 10, 64) 376 if err != nil { 377 return err 378 } 379 val = i 380 } 381 382 d.push(val) 383 return nil 384} 385 386// Push a four-byte signed int 387func (d *Decoder) loadBinInt() error { 388 var b [4]byte 389 _, err := io.ReadFull(d.r, b[:]) 390 if err != nil { 391 return err 392 } 393 v := binary.LittleEndian.Uint32(b[:]) 394 d.push(int64(v)) 395 return nil 396} 397 398// Push a 1-byte unsigned int 399func (d *Decoder) loadBinInt1() error { 400 b, err := d.r.ReadByte() 401 if err != nil { 402 return err 403 } 404 d.push(int64(b)) 405 return nil 406} 407 408// Push a long 409func (d *Decoder) loadLong() error { 410 line, err := d.readLine() 411 if err != nil { 412 return err 413 } 414 l := len(line) 415 if l < 1 || line[l-1] != 'L' { 416 return io.ErrUnexpectedEOF 417 } 418 v := new(big.Int) 419 _, ok := v.SetString(string(line[:l-1]), 10) 420 if !ok { 421 return fmt.Errorf("pickle: loadLong: invalid string") 422 } 423 d.push(v) 424 return nil 425} 426 427// Push a long1 428func (d *Decoder) loadLong1() error { 429 rawNum := []byte{} 430 b, err := d.r.ReadByte() 431 if err != nil { 432 return err 433 } 434 length, err := decodeLong(string(b)) 435 if err != nil { 436 return err 437 } 438 for i := 0; int64(i) < length.Int64(); i++ { 439 b2, err := d.r.ReadByte() 440 if err != nil { 441 return err 442 } 443 rawNum = append(rawNum, b2) 444 } 445 decodedNum, err := decodeLong(string(rawNum)) 446 d.push(decodedNum) 447 return nil 448} 449 450// Push a 2-byte unsigned int 451func (d *Decoder) loadBinInt2() error { 452 var b [2]byte 453 _, err := io.ReadFull(d.r, b[:]) 454 if err != nil { 455 return err 456 } 457 v := binary.LittleEndian.Uint16(b[:]) 458 d.push(int64(v)) 459 return nil 460} 461 462// Push None 463func (d *Decoder) loadNone() error { 464 d.push(None{}) 465 return nil 466} 467 468// Push a persistent object id 469func (d *Decoder) loadPersid() error { 470 return errNotImplemented 471} 472 473// Push a persistent object id from items on the stack 474func (d *Decoder) loadBinPersid() error { 475 return errNotImplemented 476} 477 478type Call struct { 479 Callable Class 480 Args Tuple 481} 482 483func (d *Decoder) reduce() error { 484 if len(d.stack) < 2 { 485 return errStackUnderflow 486 } 487 xargs := d.xpop() 488 xclass := d.xpop() 489 args, ok := xargs.(Tuple) 490 if !ok { 491 return fmt.Errorf("pickle: reduce: invalid args: %T", xargs) 492 } 493 class, ok := xclass.(Class) 494 if !ok { 495 return fmt.Errorf("pickle: reduce: invalid class: %T", xclass) 496 } 497 d.stack = append(d.stack, Call{Callable: class, Args: args}) 498 return nil 499} 500 501func decodeStringEscape(b []byte) string { 502 // TODO 503 return string(b) 504} 505 506// Push a string 507func (d *Decoder) loadString() error { 508 line, err := d.readLine() 509 if err != nil { 510 return err 511 } 512 513 if len(line) < 2 { 514 return io.ErrUnexpectedEOF 515 } 516 517 var delim byte 518 switch line[0] { 519 case '\'': 520 delim = '\'' 521 case '"': 522 delim = '"' 523 default: 524 return fmt.Errorf("invalid string delimiter: %c", line[0]) 525 } 526 527 if line[len(line)-1] != delim { 528 return io.ErrUnexpectedEOF 529 } 530 531 d.push(decodeStringEscape(line[1 : len(line)-1])) 532 return nil 533} 534 535func (d *Decoder) loadBinString() error { 536 var b [4]byte 537 _, err := io.ReadFull(d.r, b[:]) 538 if err != nil { 539 return err 540 } 541 v := binary.LittleEndian.Uint32(b[:]) 542 543 d.buf.Reset() 544 d.buf.Grow(int(v)) 545 _, err = io.CopyN(&d.buf, d.r, int64(v)) 546 if err != nil { 547 return err 548 } 549 d.push(d.buf.String()) 550 return nil 551} 552 553func (d *Decoder) loadShortBinString() error { 554 b, err := d.r.ReadByte() 555 if err != nil { 556 return err 557 } 558 559 d.buf.Reset() 560 d.buf.Grow(int(b)) 561 _, err = io.CopyN(&d.buf, d.r, int64(b)) 562 if err != nil { 563 return err 564 } 565 d.push(d.buf.String()) 566 return nil 567} 568 569func (d *Decoder) loadUnicode() error { 570 line, err := d.readLine() 571 572 if err != nil { 573 return err 574 } 575 sline := string(line) 576 577 d.buf.Reset() 578 d.buf.Grow(len(line)) // approximation 579 580 for len(sline) > 0 { 581 var r rune 582 var err error 583 for len(sline) > 0 && sline[0] == '\'' { 584 d.buf.WriteByte(sline[0]) 585 sline = sline[1:] 586 } 587 if len(sline) == 0 { 588 break 589 } 590 r, _, sline, err = strconv.UnquoteChar(sline, '\'') 591 if err != nil { 592 return err 593 } 594 d.buf.WriteRune(r) 595 } 596 if len(sline) > 0 { 597 return fmt.Errorf("characters remaining after loadUnicode operation: %s", sline) 598 } 599 600 d.push(d.buf.String()) 601 return nil 602} 603 604func (d *Decoder) loadBinUnicode() error { 605 var length int32 606 for i := 0; i < 4; i++ { 607 t, err := d.r.ReadByte() 608 if err != nil { 609 return err 610 } 611 length = length | (int32(t) << uint(8*i)) 612 } 613 rawB := []byte{} 614 for z := 0; int32(z) < length; z++ { 615 n, err := d.r.ReadByte() 616 if err != nil { 617 return err 618 } 619 rawB = append(rawB, n) 620 } 621 d.push(string(rawB)) 622 return nil 623} 624 625func (d *Decoder) loadAppend() error { 626 if len(d.stack) < 2 { 627 return errStackUnderflow 628 } 629 v := d.xpop() 630 l := d.stack[len(d.stack)-1] 631 switch l.(type) { 632 case []interface{}: 633 l := l.([]interface{}) 634 d.stack[len(d.stack)-1] = append(l, v) 635 default: 636 return fmt.Errorf("pickle: loadAppend: expected a list, got %T", l) 637 } 638 return nil 639} 640 641func (d *Decoder) build() error { 642 return errNotImplemented 643} 644 645type Class struct { 646 Module, Name string 647} 648 649func (d *Decoder) global() error { 650 module, err := d.readLine() 651 if err != nil { 652 return err 653 } 654 smodule := string(module) 655 name, err := d.readLine() 656 if err != nil { 657 return err 658 } 659 sname := string(name) 660 d.stack = append(d.stack, Class{Module: smodule, Name: sname}) 661 return nil 662} 663 664func (d *Decoder) loadDict() error { 665 k, err := d.marker() 666 if err != nil { 667 return err 668 } 669 670 m := make(map[interface{}]interface{}, 0) 671 items := d.stack[k+1:] 672 if len(items) % 2 != 0 { 673 return fmt.Errorf("pickle: loadDict: odd # of elements") 674 } 675 for i := 0; i < len(items); i += 2 { 676 key := items[i] 677 if !reflect.TypeOf(key).Comparable() { 678 return fmt.Errorf("pickle: loadDict: invalid key type %T", key) 679 } 680 m[key] = items[i+1] 681 } 682 d.stack = append(d.stack[:k], m) 683 return nil 684} 685 686func (d *Decoder) loadEmptyDict() error { 687 m := make(map[interface{}]interface{}, 0) 688 d.push(m) 689 return nil 690} 691 692func (d *Decoder) loadAppends() error { 693 k, err := d.marker() 694 if err != nil { 695 return err 696 } 697 if k < 1 { 698 return errStackUnderflow 699 } 700 701 l := d.stack[k-1] 702 switch l.(type) { 703 case []interface{}: 704 l := l.([]interface{}) 705 for _, v := range d.stack[k+1 : len(d.stack)] { 706 l = append(l, v) 707 } 708 d.stack = append(d.stack[:k-1], l) 709 default: 710 return fmt.Errorf("pickle: loadAppends: expected a list, got %T", l) 711 } 712 return nil 713} 714 715func (d *Decoder) get() error { 716 line, err := d.readLine() 717 if err != nil { 718 return err 719 } 720 v, ok := d.memo[string(line)] 721 if !ok { 722 return fmt.Errorf("pickle: memo: key error %q", line) 723 } 724 d.push(v) 725 return nil 726} 727 728func (d *Decoder) binGet() error { 729 b, err := d.r.ReadByte() 730 if err != nil { 731 return err 732 } 733 734 v, ok := d.memo[strconv.Itoa(int(b))] 735 if !ok { 736 return fmt.Errorf("pickle: memo: key error %d", b) 737 } 738 d.push(v) 739 return nil 740} 741 742func (d *Decoder) inst() error { 743 return errNotImplemented 744} 745 746func (d *Decoder) longBinGet() error { 747 var b [4]byte 748 _, err := io.ReadFull(d.r, b[:]) 749 if err != nil { 750 return err 751 } 752 v := binary.LittleEndian.Uint32(b[:]) 753 vv, ok := d.memo[strconv.Itoa(int(v))] 754 if !ok { 755 return fmt.Errorf("pickle: memo: key error %d", v) 756 } 757 d.push(vv) 758 return nil 759} 760 761func (d *Decoder) loadBool(b bool) error { 762 d.push(b) 763 return nil 764} 765 766func (d *Decoder) loadList() error { 767 k, err := d.marker() 768 if err != nil { 769 return err 770 } 771 772 v := append([]interface{}{}, d.stack[k+1:]...) 773 d.stack = append(d.stack[:k], v) 774 return nil 775} 776 777func (d *Decoder) loadTuple() error { 778 k, err := d.marker() 779 if err != nil { 780 return err 781 } 782 783 v := append(Tuple{}, d.stack[k+1:]...) 784 d.stack = append(d.stack[:k], v) 785 return nil 786} 787 788func (d *Decoder) loadTuple1() error { 789 if len(d.stack) < 1 { 790 return errStackUnderflow 791 } 792 k := len(d.stack) - 1 793 v := append(Tuple{}, d.stack[k:]...) 794 d.stack = append(d.stack[:k], v) 795 return nil 796} 797 798func (d *Decoder) loadTuple2() error { 799 if len(d.stack) < 2 { 800 return errStackUnderflow 801 } 802 k := len(d.stack) - 2 803 v := append(Tuple{}, d.stack[k:]...) 804 d.stack = append(d.stack[:k], v) 805 return nil 806} 807 808func (d *Decoder) loadTuple3() error { 809 if len(d.stack) < 3 { 810 return errStackUnderflow 811 } 812 k := len(d.stack) - 3 813 v := append(Tuple{}, d.stack[k:]...) 814 d.stack = append(d.stack[:k], v) 815 return nil 816} 817 818func (d *Decoder) obj() error { 819 return errNotImplemented 820} 821 822func (d *Decoder) loadPut() error { 823 line, err := d.readLine() 824 if err != nil { 825 return err 826 } 827 if len(d.stack) < 1 { 828 return errStackUnderflow 829 } 830 d.memo[string(line)] = d.stack[len(d.stack)-1] 831 return nil 832} 833 834func (d *Decoder) binPut() error { 835 if len(d.stack) < 1 { 836 return errStackUnderflow 837 } 838 b, err := d.r.ReadByte() 839 if err != nil { 840 return err 841 } 842 843 d.memo[strconv.Itoa(int(b))] = d.stack[len(d.stack)-1] 844 return nil 845} 846 847func (d *Decoder) longBinPut() error { 848 if len(d.stack) < 1 { 849 return errStackUnderflow 850 } 851 var b [4]byte 852 _, err := io.ReadFull(d.r, b[:]) 853 if err != nil { 854 return err 855 } 856 v := binary.LittleEndian.Uint32(b[:]) 857 d.memo[strconv.Itoa(int(v))] = d.stack[len(d.stack)-1] 858 return nil 859} 860 861func (d *Decoder) loadSetItem() error { 862 if len(d.stack) < 3 { 863 return errStackUnderflow 864 } 865 v := d.xpop() 866 k := d.xpop() 867 m := d.stack[len(d.stack)-1] 868 switch m := m.(type) { 869 case map[interface{}]interface{}: 870 if !reflect.TypeOf(k).Comparable() { 871 return fmt.Errorf("pickle: loadSetItem: invalid key type %T", k) 872 } 873 m[k] = v 874 default: 875 return fmt.Errorf("pickle: loadSetItem: expected a map, got %T", m) 876 } 877 return nil 878} 879 880func (d *Decoder) loadSetItems() error { 881 k, err := d.marker() 882 if err != nil { 883 return err 884 } 885 if k < 1 { 886 return errStackUnderflow 887 } 888 889 l := d.stack[k-1] 890 switch m := l.(type) { 891 case map[interface{}]interface{}: 892 if (len(d.stack) - (k + 1)) % 2 != 0 { 893 return fmt.Errorf("pickle: loadSetItems: odd # of elements") 894 } 895 for i := k + 1; i < len(d.stack); i += 2 { 896 key := d.stack[i] 897 if !reflect.TypeOf(key).Comparable() { 898 return fmt.Errorf("pickle: loadSetItems: invalid key type %T", key) 899 } 900 m[d.stack[i]] = d.stack[i+1] 901 } 902 d.stack = append(d.stack[:k-1], m) 903 default: 904 return fmt.Errorf("pickle: loadSetItems: expected a map, got %T", m) 905 } 906 return nil 907} 908 909func (d *Decoder) binFloat() error { 910 var b [8]byte 911 _, err := io.ReadFull(d.r, b[:]) 912 if err != nil { 913 return err 914 } 915 u := binary.BigEndian.Uint64(b[:]) 916 d.stack = append(d.stack, math.Float64frombits(u)) 917 return nil 918} 919 920// loadFrame discards the framing opcode+information, this information is useful to do one large read (instead of many small reads) 921// https://www.python.org/dev/peps/pep-3154/#framing 922func (d *Decoder) loadFrame() error { 923 var b [8]byte 924 _, err := io.ReadFull(d.r, b[:]) 925 if err != nil { 926 return err 927 } 928 return nil 929} 930 931func (d *Decoder) loadShortBinUnicode() error { 932 b, err := d.r.ReadByte() 933 if err != nil { 934 return err 935 } 936 937 d.buf.Reset() 938 d.buf.Grow(int(b)) 939 _, err = io.CopyN(&d.buf, d.r, int64(b)) 940 if err != nil { 941 return err 942 } 943 d.push(d.buf.String()) 944 return nil 945} 946 947func (d *Decoder) loadMemoize() error { 948 if len(d.stack) < 1 { 949 return errStackUnderflow 950 } 951 d.memo[strconv.Itoa(len(d.memo))] = d.stack[len(d.stack)-1] 952 return nil 953} 954 955// decodeLong takes a byte array of 2's compliment little-endian binary words and converts them 956// to a big integer 957func decodeLong(data string) (*big.Int, error) { 958 decoded := big.NewInt(0) 959 var negative bool 960 switch x := len(data); { 961 case x < 1: 962 return decoded, nil 963 case x > 1: 964 if data[x-1] > 127 { 965 negative = true 966 } 967 for i := x - 1; i >= 0; i-- { 968 a := big.NewInt(int64(data[i])) 969 for n := i; n > 0; n-- { 970 a = a.Lsh(a, 8) 971 } 972 decoded = decoded.Add(a, decoded) 973 } 974 default: 975 if data[0] > 127 { 976 negative = true 977 } 978 decoded = big.NewInt(int64(data[0])) 979 } 980 981 if negative { 982 // Subtract 1 from the number 983 one := big.NewInt(1) 984 decoded.Sub(decoded, one) 985 986 // Flip the bits 987 bytes := decoded.Bytes() 988 for i := 0; i < len(bytes); i++ { 989 bytes[i] = ^bytes[i] 990 } 991 decoded.SetBytes(bytes) 992 993 // Mark as negative now conversion has been completed 994 decoded.Neg(decoded) 995 } 996 return decoded, nil 997} 998