~pythonregexp2.7/python/issue2636-24

« back to all changes in this revision

Viewing changes to Modules/cPickle.c

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-09-21 13:47:31 UTC
  • mfrom: (39021.1.404 Regexp-2.7)
  • Revision ID: darklord@timehorse.com-20080921134731-rudomuzeh1b2tz1y
Merged in changes from the latest python source snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
339
339
        int bin;
340
340
 
341
341
        int fast; /* Fast mode doesn't save in memo, don't use if circ ref */
342
 
        int nesting;
343
342
        int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t);
344
343
        char *write_buf;
345
344
        int buf_size;
1516
1515
static int
1517
1516
batch_list(Picklerobject *self, PyObject *iter)
1518
1517
{
1519
 
        PyObject *obj;
1520
 
        PyObject *slice[BATCHSIZE];
 
1518
        PyObject *obj = NULL;
 
1519
        PyObject *firstitem = NULL;
1521
1520
        int i, n;
1522
1521
 
1523
1522
        static char append = APPEND;
1546
1545
 
1547
1546
        /* proto > 0:  write in batches of BATCHSIZE. */
1548
1547
        do {
1549
 
                /* Get next group of (no more than) BATCHSIZE elements. */
1550
 
                for (n = 0; n < BATCHSIZE; ++n) {
 
1548
                /* Get first item */
 
1549
                firstitem = PyIter_Next(iter);
 
1550
                if (firstitem == NULL) {
 
1551
                        if (PyErr_Occurred())
 
1552
                                goto BatchFailed;
 
1553
 
 
1554
                        /* nothing more to add */
 
1555
                        break;
 
1556
                }
 
1557
 
 
1558
                /* Try to get a second item */
 
1559
                obj = PyIter_Next(iter);
 
1560
                if (obj == NULL) {
 
1561
                        if (PyErr_Occurred())
 
1562
                                goto BatchFailed;
 
1563
 
 
1564
                        /* Only one item to write */
 
1565
                        if (save(self, firstitem, 0) < 0)
 
1566
                                goto BatchFailed;
 
1567
                        if (self->write_func(self, &append, 1) < 0)
 
1568
                                goto BatchFailed;
 
1569
                        Py_CLEAR(firstitem);
 
1570
                        break;
 
1571
                }
 
1572
 
 
1573
                /* More than one item to write */
 
1574
 
 
1575
                /* Pump out MARK, items, APPENDS. */
 
1576
                if (self->write_func(self, &MARKv, 1) < 0)
 
1577
                        goto BatchFailed;
 
1578
                
 
1579
                if (save(self, firstitem, 0) < 0)
 
1580
                        goto BatchFailed;
 
1581
                Py_CLEAR(firstitem);
 
1582
                n = 1;
 
1583
                
 
1584
                /* Fetch and save up to BATCHSIZE items */
 
1585
                while (obj) {
 
1586
                        if (save(self, obj, 0) < 0)
 
1587
                                goto BatchFailed;
 
1588
                        Py_CLEAR(obj);
 
1589
                        n += 1;
 
1590
                        
 
1591
                        if (n == BATCHSIZE)
 
1592
                                break;
 
1593
 
1551
1594
                        obj = PyIter_Next(iter);
1552
1595
                        if (obj == NULL) {
1553
1596
                                if (PyErr_Occurred())
1554
1597
                                        goto BatchFailed;
1555
1598
                                break;
1556
1599
                        }
1557
 
                        slice[n] = obj;
1558
 
                }
1559
 
 
1560
 
                if (n > 1) {
1561
 
                        /* Pump out MARK, slice[0:n], APPENDS. */
1562
 
                        if (self->write_func(self, &MARKv, 1) < 0)
1563
 
                                goto BatchFailed;
1564
 
                        for (i = 0; i < n; ++i) {
1565
 
                                if (save(self, slice[i], 0) < 0)
1566
 
                                        goto BatchFailed;
1567
 
                        }
1568
 
                        if (self->write_func(self, &appends, 1) < 0)
1569
 
                                goto BatchFailed;
1570
 
                }
1571
 
                else if (n == 1) {
1572
 
                        if (save(self, slice[0], 0) < 0)
1573
 
                                goto BatchFailed;
1574
 
                        if (self->write_func(self, &append, 1) < 0)
1575
 
                                goto BatchFailed;
1576
 
                }
1577
 
 
1578
 
                for (i = 0; i < n; ++i) {
1579
 
                        Py_DECREF(slice[i]);
1580
 
                }
 
1600
                }
 
1601
 
 
1602
                if (self->write_func(self, &appends, 1) < 0)
 
1603
                        goto BatchFailed;
 
1604
 
1581
1605
        } while (n == BATCHSIZE);
1582
1606
        return 0;
1583
1607
 
1584
1608
BatchFailed:
1585
 
        while (--n >= 0) {
1586
 
                Py_DECREF(slice[n]);
1587
 
        }
 
1609
        Py_XDECREF(firstitem);
 
1610
        Py_XDECREF(obj);
1588
1611
        return -1;
1589
1612
}
1590
1613
 
1630
1653
        iter = PyObject_GetIter(args);
1631
1654
        if (iter == NULL)
1632
1655
                goto finally;
1633
 
        res = batch_list(self, iter);
 
1656
 
 
1657
        if (Py_EnterRecursiveCall(" while pickling an object") == 0)
 
1658
        {
 
1659
                res = batch_list(self, iter);
 
1660
                Py_LeaveRecursiveCall();
 
1661
        }
1634
1662
        Py_DECREF(iter);
1635
1663
 
1636
1664
  finally:
1655
1683
static int
1656
1684
batch_dict(Picklerobject *self, PyObject *iter)
1657
1685
{
1658
 
        PyObject *p;
1659
 
        PyObject *slice[BATCHSIZE];
 
1686
        PyObject *p = NULL;
 
1687
        PyObject *firstitem = NULL;
1660
1688
        int i, n;
1661
1689
 
1662
1690
        static char setitem = SETITEM;
1692
1720
 
1693
1721
        /* proto > 0:  write in batches of BATCHSIZE. */
1694
1722
        do {
1695
 
                /* Get next group of (no more than) BATCHSIZE elements. */
1696
 
                for (n = 0; n < BATCHSIZE; ++n) {
1697
 
                        p = PyIter_Next(iter);
1698
 
                        if (p == NULL) {
1699
 
                                if (PyErr_Occurred())
1700
 
                                        goto BatchFailed;
1701
 
                                break;
1702
 
                        }
 
1723
                /* Get first item */
 
1724
                firstitem = PyIter_Next(iter);
 
1725
                if (firstitem == NULL) {
 
1726
                        if (PyErr_Occurred())
 
1727
                                goto BatchFailed;
 
1728
 
 
1729
                        /* nothing more to add */
 
1730
                        break;
 
1731
                }
 
1732
                if (!PyTuple_Check(firstitem) || PyTuple_Size(firstitem) != 2) {
 
1733
                        PyErr_SetString(PyExc_TypeError, "dict items "
 
1734
                                        "iterator must return 2-tuples");
 
1735
                        goto BatchFailed;
 
1736
                }
 
1737
 
 
1738
                /* Try to get a second item */
 
1739
                p = PyIter_Next(iter);
 
1740
                if (p == NULL) {
 
1741
                        if (PyErr_Occurred())
 
1742
                                goto BatchFailed;
 
1743
 
 
1744
                        /* Only one item to write */
 
1745
                        if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
 
1746
                                goto BatchFailed;
 
1747
                        if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
 
1748
                                goto BatchFailed;
 
1749
                        if (self->write_func(self, &setitem, 1) < 0)
 
1750
                                goto BatchFailed;
 
1751
                        Py_CLEAR(firstitem);
 
1752
                        break;
 
1753
                }
 
1754
 
 
1755
                /* More than one item to write */
 
1756
 
 
1757
                /* Pump out MARK, items, SETITEMS. */
 
1758
                if (self->write_func(self, &MARKv, 1) < 0)
 
1759
                        goto BatchFailed;
 
1760
 
 
1761
                if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
 
1762
                        goto BatchFailed;
 
1763
                if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
 
1764
                        goto BatchFailed;
 
1765
                Py_CLEAR(firstitem);
 
1766
                n = 1;
 
1767
 
 
1768
                /* Fetch and save up to BATCHSIZE items */
 
1769
                while (p) {
1703
1770
                        if (!PyTuple_Check(p) || PyTuple_Size(p) != 2) {
1704
1771
                                PyErr_SetString(PyExc_TypeError, "dict items "
1705
1772
                                        "iterator must return 2-tuples");
1706
1773
                                goto BatchFailed;
1707
1774
                        }
1708
 
                        slice[n] = p;
1709
 
                }
1710
 
 
1711
 
                if (n > 1) {
1712
 
                        /* Pump out MARK, slice[0:n], SETITEMS. */
1713
 
                        if (self->write_func(self, &MARKv, 1) < 0)
1714
 
                                goto BatchFailed;
1715
 
                        for (i = 0; i < n; ++i) {
1716
 
                                p = slice[i];
1717
 
                                if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
1718
 
                                        goto BatchFailed;
1719
 
                                if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
1720
 
                                        goto BatchFailed;
1721
 
                        }
1722
 
                        if (self->write_func(self, &setitems, 1) < 0)
1723
 
                                goto BatchFailed;
1724
 
                }
1725
 
                else if (n == 1) {
1726
 
                        p = slice[0];
1727
1775
                        if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
1728
1776
                                goto BatchFailed;
1729
1777
                        if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
1730
1778
                                goto BatchFailed;
1731
 
                        if (self->write_func(self, &setitem, 1) < 0)
1732
 
                                goto BatchFailed;
1733
 
                }
1734
 
 
1735
 
                for (i = 0; i < n; ++i) {
1736
 
                        Py_DECREF(slice[i]);
1737
 
                }
 
1779
                        Py_CLEAR(p);
 
1780
                        n += 1;
 
1781
 
 
1782
                        if (n == BATCHSIZE)
 
1783
                                break;
 
1784
 
 
1785
                        p = PyIter_Next(iter);
 
1786
                        if (p == NULL) {
 
1787
                                if (PyErr_Occurred())
 
1788
                                        goto BatchFailed;
 
1789
                                break;
 
1790
                        }
 
1791
                }
 
1792
 
 
1793
                if (self->write_func(self, &setitems, 1) < 0)
 
1794
                        goto BatchFailed;
 
1795
 
1738
1796
        } while (n == BATCHSIZE);
1739
1797
        return 0;
1740
1798
 
1741
1799
BatchFailed:
1742
 
        while (--n >= 0) {
1743
 
                Py_DECREF(slice[n]);
1744
 
        }
 
1800
        Py_XDECREF(firstitem);
 
1801
        Py_XDECREF(p);
1745
1802
        return -1;
1746
1803
}
1747
1804
 
1786
1843
        iter = PyObject_CallMethod(args, "iteritems", "()");
1787
1844
        if (iter == NULL)
1788
1845
                goto finally;
1789
 
        res = batch_dict(self, iter);
 
1846
        if (Py_EnterRecursiveCall(" while pickling an object") == 0)
 
1847
        {
 
1848
                res = batch_dict(self, iter);
 
1849
                Py_LeaveRecursiveCall();
 
1850
        }
1790
1851
        Py_DECREF(iter);
1791
1852
 
1792
1853
  finally:
2306
2367
        int res = -1;
2307
2368
        int tmp, size;
2308
2369
 
2309
 
        if (self->nesting++ > Py_GetRecursionLimit()){
2310
 
                PyErr_SetString(PyExc_RuntimeError,
2311
 
                                "maximum recursion depth exceeded");
2312
 
                goto finally;
2313
 
        }
 
2370
        if (Py_EnterRecursiveCall(" while pickling an object"))
 
2371
                return -1;
2314
2372
 
2315
2373
        if (!pers_save && self->pers_func) {
2316
2374
                if ((tmp = save_pers(self, args, self->pers_func)) != 0) {
2366
2424
                        res = save_string(self, args, 0);
2367
2425
                        goto finally;
2368
2426
                }
 
2427
                break;
2369
2428
 
2370
2429
#ifdef Py_USING_UNICODE
2371
2430
        case 'u':
2373
2432
                        res = save_unicode(self, args, 0);
2374
2433
                        goto finally;
2375
2434
                }
 
2435
                break;
2376
2436
#endif
2377
2437
        }
2378
2438
 
2557
2617
        res = save_reduce(self, t, args);
2558
2618
 
2559
2619
  finally:
2560
 
        self->nesting--;
 
2620
        Py_LeaveRecursiveCall();
2561
2621
        Py_XDECREF(py_ob_id);
2562
2622
        Py_XDECREF(__reduce__);
2563
2623
        Py_XDECREF(t);
2799
2859
        self->inst_pers_func = NULL;
2800
2860
        self->write_buf = NULL;
2801
2861
        self->fast = 0;
2802
 
        self->nesting = 0;
2803
2862
        self->fast_container = 0;
2804
2863
        self->fast_memo = NULL;
2805
2864
        self->buf_size = 0;
3435
3494
        if (self->read_func(self, &s, 4) < 0) return -1;
3436
3495
 
3437
3496
        l = calc_binint(s, 4);
 
3497
        if (l < 0) {
 
3498
                /* Corrupt or hostile pickle -- we never write one like
 
3499
                 * this.
 
3500
                 */
 
3501
                PyErr_SetString(UnpicklingError,
 
3502
                                "BINSTRING pickle has negative byte count");
 
3503
                return -1;
 
3504
        }
3438
3505
 
3439
3506
        if (self->read_func(self, &s, l) < 0)
3440
3507
                return -1;
3502
3569
        if (self->read_func(self, &s, 4) < 0) return -1;
3503
3570
 
3504
3571
        l = calc_binint(s, 4);
 
3572
        if (l < 0) {
 
3573
                /* Corrupt or hostile pickle -- we never write one like
 
3574
                 * this.
 
3575
                 */
 
3576
                PyErr_SetString(UnpicklingError,
 
3577
                                "BINUNICODE pickle has negative byte count");
 
3578
                return -1;
 
3579
        }
3505
3580
 
3506
3581
        if (self->read_func(self, &s, l) < 0)
3507
3582
                return -1;