summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c14
-rw-r--r--Objects/classobject.c2
-rw-r--r--Objects/dictobject.c24
-rw-r--r--Objects/exceptions.c52
-rw-r--r--Objects/fileobject.c33
-rw-r--r--Objects/intobject.c42
-rw-r--r--Objects/listobject.c31
-rw-r--r--Objects/longobject.c71
-rw-r--r--Objects/obmalloc.c3
-rw-r--r--Objects/setobject.c123
-rw-r--r--Objects/stringlib/partition.h8
-rw-r--r--Objects/stringobject.c45
-rw-r--r--Objects/tupleobject.c5
-rw-r--r--Objects/typeobject.c23
-rw-r--r--Objects/unicodeobject.c52
15 files changed, 366 insertions, 162 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 8810762..03883be 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1524,20 +1524,18 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
if (cmp > 0) {
switch (operation) {
case PY_ITERSEARCH_COUNT:
- ++n;
- if (n <= 0) {
- /* XXX(nnorwitz): int means ssize_t */
+ if (n == PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "count exceeds C int size");
+ "count exceeds C integer size");
goto Fail;
}
+ ++n;
break;
case PY_ITERSEARCH_INDEX:
if (wrapped) {
- /* XXX(nnorwitz): int means ssize_t */
PyErr_SetString(PyExc_OverflowError,
- "index exceeds C int size");
+ "index exceeds C integer size");
goto Fail;
}
goto Done;
@@ -1552,9 +1550,9 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
}
if (operation == PY_ITERSEARCH_INDEX) {
- ++n;
- if (n <= 0)
+ if (n == PY_SSIZE_T_MAX)
wrapped = 1;
+ ++n;
}
}
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 1107977..85826a9 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -152,6 +152,8 @@ method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
PyObject *self;
PyObject *classObj = NULL;
+ if (!_PyArg_NoKeywords("instancemethod", kw))
+ return NULL;
if (!PyArg_UnpackTuple(args, "method", 2, 3,
&func, &self, &classObj))
return NULL;
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 64585a4..09aba61 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -12,6 +12,20 @@
typedef PyDictEntry dictentry;
typedef PyDictObject dictobject;
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+ PyObject *tup;
+ tup = PyTuple_Pack(1, arg);
+ if (!tup)
+ return; /* caller will expect error to be set anyway */
+ PyErr_SetObject(PyExc_KeyError, tup);
+ Py_DECREF(tup);
+}
+
/* Define this out if you don't want conversion statistics on exit. */
#undef SHOW_CONVERSION_COUNTS
@@ -307,6 +321,8 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
else if (ep->me_key == dummy && freeslot == NULL)
freeslot = ep;
}
+ assert(0); /* NOT REACHED */
+ return 0;
}
/*
@@ -366,6 +382,8 @@ lookdict_string(dictobject *mp, PyObject *key, register long hash)
if (ep->me_key == dummy && freeslot == NULL)
freeslot = ep;
}
+ assert(0); /* NOT REACHED */
+ return 0;
}
/*
@@ -691,7 +709,7 @@ PyDict_DelItem(PyObject *op, PyObject *key)
if (ep == NULL)
return -1;
if (ep->me_value == NULL) {
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return -1;
}
old_key = ep->me_key;
@@ -1000,7 +1018,7 @@ dict_subscript(dictobject *mp, register PyObject *key)
return PyObject_CallFunctionObjArgs(missing,
(PyObject *)mp, key, NULL);
}
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return NULL;
}
else
@@ -1644,7 +1662,7 @@ dict_pop(dictobject *mp, PyObject *args)
Py_INCREF(deflt);
return deflt;
}
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return NULL;
}
old_key = ep->me_key;
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index c3ead69..0cd819c 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -81,6 +81,7 @@ BaseException_clear(PyBaseExceptionObject *self)
static void
BaseException_dealloc(PyBaseExceptionObject *self)
{
+ _PyObject_GC_UNTRACK(self);
BaseException_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -174,27 +175,10 @@ BaseException_setstate(PyObject *self, PyObject *state)
Py_RETURN_NONE;
}
-#ifdef Py_USING_UNICODE
-/* while this method generates fairly uninspired output, it a least
- * guarantees that we can display exceptions that have unicode attributes
- */
-static PyObject *
-BaseException_unicode(PyBaseExceptionObject *self)
-{
- if (PyTuple_GET_SIZE(self->args) == 0)
- return PyUnicode_FromUnicode(NULL, 0);
- if (PyTuple_GET_SIZE(self->args) == 1)
- return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
- return PyObject_Unicode(self->args);
-}
-#endif /* Py_USING_UNICODE */
static PyMethodDef BaseException_methods[] = {
{"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
{"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
-#ifdef Py_USING_UNICODE
- {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
-#endif
{NULL, NULL, 0, NULL},
};
@@ -206,12 +190,19 @@ BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
return PySequence_GetItem(self->args, index);
}
+static PyObject *
+BaseException_getslice(PyBaseExceptionObject *self,
+ Py_ssize_t start, Py_ssize_t stop)
+{
+ return PySequence_GetSlice(self->args, start, stop);
+}
+
static PySequenceMethods BaseException_as_sequence = {
0, /* sq_length; */
0, /* sq_concat; */
0, /* sq_repeat; */
(ssizeargfunc)BaseException_getitem, /* sq_item; */
- 0, /* sq_slice; */
+ (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */
0, /* sq_ass_item; */
0, /* sq_ass_slice; */
0, /* sq_contains; */
@@ -456,6 +447,7 @@ SystemExit_clear(PySystemExitObject *self)
static void
SystemExit_dealloc(PySystemExitObject *self)
{
+ _PyObject_GC_UNTRACK(self);
SystemExit_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -518,7 +510,7 @@ EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
return -1;
- if (PyTuple_GET_SIZE(args) <= 1) {
+ if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
return 0;
}
@@ -562,6 +554,7 @@ EnvironmentError_clear(PyEnvironmentErrorObject *self)
static void
EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
{
+ _PyObject_GC_UNTRACK(self);
EnvironmentError_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -760,6 +753,7 @@ WindowsError_clear(PyWindowsErrorObject *self)
static void
WindowsError_dealloc(PyWindowsErrorObject *self)
{
+ _PyObject_GC_UNTRACK(self);
WindowsError_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -834,9 +828,9 @@ WindowsError_str(PyWindowsErrorObject *self)
return NULL;
}
- if (self->myerrno) {
- Py_INCREF(self->myerrno);
- PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+ if (self->winerror) {
+ Py_INCREF(self->winerror);
+ PyTuple_SET_ITEM(tuple, 0, self->winerror);
}
else {
Py_INCREF(Py_None);
@@ -858,7 +852,7 @@ WindowsError_str(PyWindowsErrorObject *self)
Py_DECREF(fmt);
Py_DECREF(tuple);
}
- else if (self->myerrno && self->strerror) {
+ else if (self->winerror && self->strerror) {
PyObject *fmt;
PyObject *tuple;
@@ -872,9 +866,9 @@ WindowsError_str(PyWindowsErrorObject *self)
return NULL;
}
- if (self->myerrno) {
- Py_INCREF(self->myerrno);
- PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+ if (self->winerror) {
+ Py_INCREF(self->winerror);
+ PyTuple_SET_ITEM(tuple, 0, self->winerror);
}
else {
Py_INCREF(Py_None);
@@ -1035,6 +1029,7 @@ SyntaxError_clear(PySyntaxErrorObject *self)
static void
SyntaxError_dealloc(PySyntaxErrorObject *self)
{
+ _PyObject_GC_UNTRACK(self);
SyntaxError_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -1551,6 +1546,7 @@ UnicodeError_clear(PyUnicodeErrorObject *self)
static void
UnicodeError_dealloc(PyUnicodeErrorObject *self)
{
+ _PyObject_GC_UNTRACK(self);
UnicodeError_clear(self);
self->ob_type->tp_free((PyObject *)self);
}
@@ -1637,7 +1633,7 @@ UnicodeEncodeError_str(PyObject *self)
static PyTypeObject _PyExc_UnicodeEncodeError = {
PyObject_HEAD_INIT(NULL)
0,
- "UnicodeEncodeError",
+ EXC_MODULE_NAME "UnicodeEncodeError",
sizeof(PyUnicodeErrorObject), 0,
(destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(reprfunc)UnicodeEncodeError_str, 0, 0, 0,
@@ -1812,7 +1808,7 @@ static PyTypeObject _PyExc_UnicodeTranslateError = {
(destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(reprfunc)UnicodeTranslateError_str, 0, 0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
+ PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
(inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
(initproc)UnicodeTranslateError_init, 0, BaseException_new,
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index fb8a542..f2aeb9d 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -540,7 +540,7 @@ file_seek(PyFileObject *f, PyObject *args)
int whence;
int ret;
Py_off_t offset;
- PyObject *offobj;
+ PyObject *offobj, *off_index;
if (f->f_fp == NULL)
return err_closed();
@@ -548,12 +548,25 @@ file_seek(PyFileObject *f, PyObject *args)
whence = 0;
if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
return NULL;
+ off_index = PyNumber_Index(offobj);
+ if (!off_index) {
+ if (!PyFloat_Check(offobj))
+ return NULL;
+ /* Deprecated in 2.6 */
+ PyErr_Clear();
+ if (PyErr_Warn(PyExc_DeprecationWarning,
+ "integer argument expected, got float"))
+ return NULL;
+ off_index = offobj;
+ Py_INCREF(offobj);
+ }
#if !defined(HAVE_LARGEFILE_SUPPORT)
- offset = PyInt_AsLong(offobj);
+ offset = PyInt_AsLong(off_index);
#else
- offset = PyLong_Check(offobj) ?
- PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
+ offset = PyLong_Check(off_index) ?
+ PyLong_AsLongLong(off_index) : PyInt_AsLong(off_index);
#endif
+ Py_DECREF(off_index);
if (PyErr_Occurred())
return NULL;
@@ -927,7 +940,7 @@ file_readinto(PyFileObject *f, PyObject *args)
ndone += nnow;
ntodo -= nnow;
}
- return PyInt_FromLong((long)ndone);
+ return PyInt_FromSsize_t(ndone);
}
/**************************************************************************
@@ -1006,6 +1019,7 @@ getline_via_fgets(FILE *fp)
size_t nfree; /* # of free buffer slots; pvend-pvfree */
size_t total_v_size; /* total # of slots in buffer */
size_t increment; /* amount to increment the buffer */
+ size_t prev_v_size;
/* Optimize for normal case: avoid _PyString_Resize if at all
* possible via first reading into stack buffer "buf".
@@ -1120,8 +1134,11 @@ getline_via_fgets(FILE *fp)
/* expand buffer and try again */
assert(*(pvend-1) == '\0');
increment = total_v_size >> 2; /* mild exponential growth */
+ prev_v_size = total_v_size;
total_v_size += increment;
- if (total_v_size > PY_SSIZE_T_MAX) {
+ /* check for overflow */
+ if (total_v_size <= prev_v_size ||
+ total_v_size > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"line is longer than a Python string can hold");
Py_DECREF(v);
@@ -1130,7 +1147,7 @@ getline_via_fgets(FILE *fp)
if (_PyString_Resize(&v, (int)total_v_size) < 0)
return NULL;
/* overwrite the trailing null byte */
- pvfree = BUF(v) + (total_v_size - increment - 1);
+ pvfree = BUF(v) + (prev_v_size - 1);
}
if (BUF(v) + total_v_size != p)
_PyString_Resize(&v, p - BUF(v));
@@ -2014,7 +2031,7 @@ file_init(PyObject *self, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file",
kwlist, &o_name, &mode,
&bufsize))
- return -1;
+ goto Error;
if (fill_file_fields(foself, NULL, o_name, mode,
fclose) == NULL)
diff --git a/Objects/intobject.c b/Objects/intobject.c
index b420c12..0b746de 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -557,6 +557,17 @@ int_mul(PyObject *v, PyObject *w)
}
}
+/* Integer overflow checking for unary negation: on a 2's-complement
+ * box, -x overflows iff x is the most negative long. In this case we
+ * get -x == x. However, -x is undefined (by C) if x /is/ the most
+ * negative long (it's a signed overflow case), and some compilers care.
+ * So we cast x to unsigned long first. However, then other compilers
+ * warn about applying unary minus to an unsigned operand. Hence the
+ * weird "0-".
+ */
+#define UNARY_NEG_WOULD_OVERFLOW(x) \
+ ((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))
+
/* Return type of i_divmod */
enum divmod_result {
DIVMOD_OK, /* Correct result */
@@ -576,7 +587,7 @@ i_divmod(register long x, register long y,
return DIVMOD_ERROR;
}
/* (-sys.maxint-1)/-1 is the only overflow case. */
- if (y == -1 && x < 0 && x == -x)
+ if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
return DIVMOD_OVERFLOW;
xdivy = x / y;
xmody = x - xdivy * y;
@@ -744,10 +755,10 @@ int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
static PyObject *
int_neg(PyIntObject *v)
{
- register long a, x;
+ register long a;
a = v->ob_ival;
- x = -a;
- if (a < 0 && x < 0) {
+ /* check for overflow */
+ if (UNARY_NEG_WOULD_OVERFLOW(a)) {
PyObject *o = PyLong_FromLong(a);
if (o != NULL) {
PyObject *result = PyNumber_Negative(o);
@@ -756,7 +767,7 @@ int_neg(PyIntObject *v)
}
return NULL;
}
- return PyInt_FromLong(x);
+ return PyInt_FromLong(-a);
}
static PyObject *
@@ -955,8 +966,25 @@ int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return PyInt_FromLong(0L);
if (base == -909)
return PyNumber_Int(x);
- if (PyString_Check(x))
- return PyInt_FromString(PyString_AS_STRING(x), NULL, base);
+ if (PyString_Check(x)) {
+ /* Since PyInt_FromString doesn't have a length parameter,
+ * check here for possible NULs in the string. */
+ char *string = PyString_AS_STRING(x);
+ if (strlen(string) != PyString_Size(x)) {
+ /* create a repr() of the input string,
+ * just like PyInt_FromString does */
+ PyObject *srepr;
+ srepr = PyObject_Repr(x);
+ if (srepr == NULL)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "invalid literal for int() with base %d: %s",
+ base, PyString_AS_STRING(srepr));
+ Py_DECREF(srepr);
+ return NULL;
+ }
+ return PyInt_FromString(string, NULL, base);
+ }
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(x))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 9a11680..4c9c4c3 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -863,17 +863,12 @@ static PyObject *
listpop(PyListObject *self, PyObject *args)
{
Py_ssize_t i = -1;
- PyObject *v, *arg = NULL;
+ PyObject *v;
int status;
- if (!PyArg_UnpackTuple(args, "pop", 0, 1, &arg))
+ if (!PyArg_ParseTuple(args, "|n:pop", &i))
return NULL;
- if (arg != NULL) {
- if (PyInt_Check(arg))
- i = PyInt_AS_LONG((PyIntObject*) arg);
- else if (!PyArg_ParseTuple(args, "|n:pop", &i))
- return NULL;
- }
+
if (self->ob_size == 0) {
/* Special-case most common failure cause */
PyErr_SetString(PyExc_IndexError, "pop from empty list");
@@ -951,9 +946,10 @@ islt(PyObject *x, PyObject *y, PyObject *compare)
if (res == NULL)
return -1;
if (!PyInt_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "comparison function must return int, not %.200s",
+ res->ob_type->tp_name);
Py_DECREF(res);
- PyErr_SetString(PyExc_TypeError,
- "comparison function must return int");
return -1;
}
i = PyInt_AsLong(res);
@@ -2507,8 +2503,9 @@ list_subscript(PyListObject* self, PyObject* item)
}
}
else {
- PyErr_SetString(PyExc_TypeError,
- "list indices must be integers");
+ PyErr_Format(PyExc_TypeError,
+ "list indices must be integers, not %.200s",
+ item->ob_type->tp_name);
return NULL;
}
}
@@ -2624,6 +2621,11 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
garbage = (PyObject**)
PyMem_MALLOC(slicelength*sizeof(PyObject*));
+ if (!garbage) {
+ Py_DECREF(seq);
+ PyErr_NoMemory();
+ return -1;
+ }
selfitems = self->ob_item;
seqitems = PySequence_Fast_ITEMS(seq);
@@ -2646,8 +2648,9 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
}
}
else {
- PyErr_SetString(PyExc_TypeError,
- "list indices must be integers");
+ PyErr_Format(PyExc_TypeError,
+ "list indices must be integers, not %.200s",
+ item->ob_type->tp_name);
return -1;
}
}
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 566e6a7..f68656b 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -191,6 +191,18 @@ PyLong_FromDouble(double dval)
return (PyObject *)v;
}
+/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
+ * anything about what happens when a signed integer operation overflows,
+ * and some compilers think they're doing you a favor by being "clever"
+ * then. The bit pattern for the largest postive signed long is
+ * (unsigned long)LONG_MAX, and for the smallest negative signed long
+ * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
+ * However, some other compilers warn about applying unary minus to an
+ * unsigned operand. Hence the weird "0-".
+ */
+#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
+#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
+
/* Get a C long int from a long int object.
Returns -1 and sets an error condition if overflow occurs. */
@@ -223,14 +235,16 @@ PyLong_AsLong(PyObject *vv)
if ((x >> SHIFT) != prev)
goto overflow;
}
- /* Haven't lost any bits, but if the sign bit is set we're in
- * trouble *unless* this is the min negative number. So,
- * trouble iff sign bit set && (positive || some bit set other
- * than the sign bit).
- */
- if ((long)x < 0 && (sign > 0 || (x << 1) != 0))
- goto overflow;
- return (long)x * sign;
+ /* Haven't lost any bits, but casting to long requires extra care
+ * (see comment above).
+ */
+ if (x <= (unsigned long)LONG_MAX) {
+ return (long)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_LONG_MIN) {
+ return LONG_MIN;
+ }
+ /* else overflow */
overflow:
PyErr_SetString(PyExc_OverflowError,
@@ -266,14 +280,16 @@ _PyLong_AsSsize_t(PyObject *vv) {
if ((x >> SHIFT) != prev)
goto overflow;
}
- /* Haven't lost any bits, but if the sign bit is set we're in
- * trouble *unless* this is the min negative number. So,
- * trouble iff sign bit set && (positive || some bit set other
- * than the sign bit).
+ /* Haven't lost any bits, but casting to a signed type requires
+ * extra care (see comment above).
*/
- if ((Py_ssize_t)x < 0 && (sign > 0 || (x << 1) != 0))
- goto overflow;
- return (Py_ssize_t)x * sign;
+ if (x <= (size_t)PY_SSIZE_T_MAX) {
+ return (Py_ssize_t)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
+ return PY_SSIZE_T_MIN;
+ }
+ /* else overflow */
overflow:
PyErr_SetString(PyExc_OverflowError,
@@ -1165,7 +1181,7 @@ long_format(PyObject *aa, int base)
{
register PyLongObject *a = (PyLongObject *)aa;
PyStringObject *str;
- Py_ssize_t i;
+ Py_ssize_t i, j, sz;
Py_ssize_t size_a;
char *p;
int bits;
@@ -1185,11 +1201,18 @@ long_format(PyObject *aa, int base)
++bits;
i >>= 1;
}
- i = 5 + (size_a*SHIFT + bits-1) / bits;
- str = (PyStringObject *) PyString_FromStringAndSize((char *)0, i);
+ i = 5;
+ j = size_a*SHIFT + bits-1;
+ sz = i + j / bits;
+ if (j / SHIFT < size_a || sz < i) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long is too large to format");
+ return NULL;
+ }
+ str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
if (str == NULL)
return NULL;
- p = PyString_AS_STRING(str) + i;
+ p = PyString_AS_STRING(str) + sz;
*p = '\0';
if (a->ob_size < 0)
sign = '-';
@@ -1301,7 +1324,7 @@ long_format(PyObject *aa, int base)
} while ((*q++ = *p++) != '\0');
q--;
_PyString_Resize((PyObject **)&str,
- (int) (q - PyString_AS_STRING(str)));
+ (Py_ssize_t) (q - PyString_AS_STRING(str)));
}
return (PyObject *)str;
}
@@ -1359,14 +1382,14 @@ long_from_binary_base(char **str, int base)
while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
++p;
*str = p;
- n = (p - start) * bits_per_char;
- if (n / bits_per_char != p - start) {
+ /* n <- # of Python digits needed, = ceiling(n/SHIFT). */
+ n = (p - start) * bits_per_char + SHIFT - 1;
+ if (n / bits_per_char < p - start) {
PyErr_SetString(PyExc_ValueError,
"long string too large to convert");
return NULL;
}
- /* n <- # of Python digits needed, = ceiling(n/SHIFT). */
- n = (n + SHIFT - 1) / SHIFT;
+ n = n / SHIFT;
z = _PyLong_New(n);
if (z == NULL)
return NULL;
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 0ca8f2b..840570e 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -691,7 +691,8 @@ extremely desirable that it be this fast.
#undef Py_ADDRESS_IN_RANGE
-#if defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)
+#if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \
+ (__GNUC__ >= 4))
#define Py_NO_INLINE __attribute__((__noinline__))
#else
#define Py_NO_INLINE
diff --git a/Objects/setobject.c b/Objects/setobject.c
index d489711..0af1f15 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -10,6 +10,20 @@
#include "Python.h"
#include "structmember.h"
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+ PyObject *tup;
+ tup = PyTuple_Pack(1, arg);
+ if (!tup)
+ return; /* caller will expect error to be set anyway */
+ PyErr_SetObject(PyExc_KeyError, tup);
+ Py_DECREF(tup);
+}
+
/* This must be >= 1. */
#define PERTURB_SHIFT 5
@@ -179,11 +193,13 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
if (entry->key == dummy && freeslot == NULL)
freeslot = entry;
}
+ assert(0); /* NOT REACHED */
+ return 0;
}
/*
Internal routine to insert a new key into the table.
-Used both by the internal resize routine and by the public insert routine.
+Used by the public insert routine.
Eats a reference to key.
*/
static int
@@ -216,6 +232,35 @@ set_insert_key(register PySetObject *so, PyObject *key, long hash)
}
/*
+Internal routine used by set_table_resize() to insert an item which is
+known to be absent from the set. This routine also assumes that
+the set contains no deleted entries. Besides the performance benefit,
+using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key`.
+*/
+static void
+set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+{
+ register size_t i;
+ register size_t perturb;
+ register size_t mask = (size_t)so->mask;
+ setentry *table = so->table;
+ register setentry *entry;
+
+ i = hash & mask;
+ entry = &table[i];
+ for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ entry = &table[i & mask];
+ }
+ so->fill++;
+ entry->key = key;
+ entry->hash = hash;
+ so->used++;
+}
+
+/*
Restructure the table by allocating a new table and reinserting all
keys again. When entries have been deleted, the new table may
actually be smaller than the old one.
@@ -296,11 +341,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
} else {
/* ACTIVE */
--i;
- if(set_insert_key(so, entry->key, entry->hash) == -1) {
- if (is_oldtable_malloced)
- PyMem_DEL(oldtable);
- return -1;
- }
+ set_insert_clean(so, entry->key, entry->hash);
}
}
@@ -319,8 +360,10 @@ set_add_entry(register PySetObject *so, setentry *entry)
assert(so->fill <= so->mask); /* at least one empty slot */
n_used = so->used;
Py_INCREF(entry->key);
- if (set_insert_key(so, entry->key, entry->hash) == -1)
+ if (set_insert_key(so, entry->key, entry->hash) == -1) {
+ Py_DECREF(entry->key);
return -1;
+ }
if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
return 0;
return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
@@ -1155,7 +1198,12 @@ set_intersection(PySetObject *so, PyObject *other)
}
while (set_next((PySetObject *)other, &pos, &entry)) {
- if (set_contains_entry(so, entry)) {
+ int rv = set_contains_entry(so, entry);
+ if (rv == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (rv) {
if (set_add_entry(result, entry) == -1) {
Py_DECREF(result);
return NULL;
@@ -1172,8 +1220,27 @@ set_intersection(PySetObject *so, PyObject *other)
}
while ((key = PyIter_Next(it)) != NULL) {
- if (set_contains_key(so, key)) {
- if (set_add_key(result, key) == -1) {
+ int rv;
+ setentry entry;
+ long hash = PyObject_Hash(key);
+
+ if (hash == -1) {
+ Py_DECREF(it);
+ Py_DECREF(result);
+ Py_DECREF(key);
+ return NULL;
+ }
+ entry.hash = hash;
+ entry.key = key;
+ rv = set_contains_entry(so, &entry);
+ if (rv == -1) {
+ Py_DECREF(it);
+ Py_DECREF(result);
+ Py_DECREF(key);
+ return NULL;
+ }
+ if (rv) {
+ if (set_add_entry(result, &entry) == -1) {
Py_DECREF(it);
Py_DECREF(result);
Py_DECREF(key);
@@ -1249,7 +1316,8 @@ set_difference_update_internal(PySetObject *so, PyObject *other)
Py_ssize_t pos = 0;
while (set_next((PySetObject *)other, &pos, &entry))
- set_discard_entry(so, entry);
+ if (set_discard_entry(so, entry) == -1)
+ return -1;
} else {
PyObject *key, *it;
it = PyObject_GetIter(other);
@@ -1312,17 +1380,26 @@ set_difference(PySetObject *so, PyObject *other)
entrycopy.hash = entry->hash;
entrycopy.key = entry->key;
if (!PyDict_Contains(other, entry->key)) {
- if (set_add_entry((PySetObject *)result, &entrycopy) == -1)
+ if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
+ Py_DECREF(result);
return NULL;
+ }
}
}
return result;
}
while (set_next(so, &pos, &entry)) {
- if (!set_contains_entry((PySetObject *)other, entry)) {
- if (set_add_entry((PySetObject *)result, entry) == -1)
+ int rv = set_contains_entry((PySetObject *)other, entry);
+ if (rv == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (!rv) {
+ if (set_add_entry((PySetObject *)result, entry) == -1) {
+ Py_DECREF(result);
return NULL;
+ }
}
}
return result;
@@ -1374,11 +1451,18 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
PyObject *value;
int rv;
while (PyDict_Next(other, &pos, &key, &value)) {
- rv = set_discard_key(so, key);
+ setentry an_entry;
+ long hash = PyObject_Hash(key);
+
+ if (hash == -1)
+ return NULL;
+ an_entry.hash = hash;
+ an_entry.key = key;
+ rv = set_discard_entry(so, &an_entry);
if (rv == -1)
return NULL;
if (rv == DISCARD_NOTFOUND) {
- if (set_add_key(so, key) == -1)
+ if (set_add_entry(so, &an_entry) == -1)
return NULL;
}
}
@@ -1481,7 +1565,10 @@ set_issubset(PySetObject *so, PyObject *other)
Py_RETURN_FALSE;
while (set_next(so, &pos, &entry)) {
- if (!set_contains_entry((PySetObject *)other, entry))
+ int rv = set_contains_entry((PySetObject *)other, entry);
+ if (rv == -1)
+ return NULL;
+ if (!rv)
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
@@ -1628,7 +1715,7 @@ set_remove(PySetObject *so, PyObject *key)
Py_DECREF(tmpkey);
return result;
} else if (rv == DISCARD_NOTFOUND) {
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return NULL;
}
Py_RETURN_NONE;
diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h
index 1486347..105ba31 100644
--- a/Objects/stringlib/partition.h
+++ b/Objects/stringlib/partition.h
@@ -78,12 +78,12 @@ stringlib_rpartition(
}
if (pos < 0) {
- Py_INCREF(str_obj);
- PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
Py_INCREF(STRINGLIB_EMPTY);
- PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
Py_INCREF(STRINGLIB_EMPTY);
- PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+ Py_INCREF(str_obj);
+ PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
return out;
}
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 028b375..61e6af5 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -804,10 +804,22 @@ string_print(PyStringObject *op, FILE *fp, int flags)
return ret;
}
if (flags & Py_PRINT_RAW) {
+ char *data = op->ob_sval;
+ Py_ssize_t size = op->ob_size;
+ while (size > INT_MAX) {
+ /* Very long strings cannot be written atomically.
+ * But don't write exactly INT_MAX bytes at a time
+ * to avoid memory aligment issues.
+ */
+ const int chunk_size = INT_MAX & ~0x3FFF;
+ fwrite(data, 1, chunk_size, fp);
+ data += chunk_size;
+ size -= chunk_size;
+ }
#ifdef __VMS
- if (op->ob_size) fwrite(op->ob_sval, (int) op->ob_size, 1, fp);
+ if (size) fwrite(data, (int)size, 1, fp);
#else
- fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
+ fwrite(data, 1, (int)size, fp);
#endif
return 0;
}
@@ -844,7 +856,7 @@ PyString_Repr(PyObject *obj, int smartquotes)
register PyStringObject* op = (PyStringObject*) obj;
size_t newsize = 2 + 4 * op->ob_size;
PyObject *v;
- if (newsize > PY_SSIZE_T_MAX) {
+ if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {
PyErr_SetString(PyExc_OverflowError,
"string is too large to make repr");
}
@@ -1059,8 +1071,9 @@ string_contains(PyObject *str_obj, PyObject *sub_obj)
return PyUnicode_Contains(str_obj, sub_obj);
#endif
if (!PyString_Check(sub_obj)) {
- PyErr_SetString(PyExc_TypeError,
- "'in <string>' requires string as left operand");
+ PyErr_Format(PyExc_TypeError,
+ "'in <string>' requires string as left operand, "
+ "not %.200s", sub_obj->ob_type->tp_name);
return -1;
}
}
@@ -1228,8 +1241,9 @@ string_subscript(PyStringObject* self, PyObject* item)
}
}
else {
- PyErr_SetString(PyExc_TypeError,
- "string indices must be integers");
+ PyErr_Format(PyExc_TypeError,
+ "string indices must be integers, not %.200s",
+ item->ob_type->tp_name);
return NULL;
}
}
@@ -1543,11 +1557,11 @@ string_partition(PyStringObject *self, PyObject *sep_obj)
}
PyDoc_STRVAR(rpartition__doc__,
-"S.rpartition(sep) -> (head, sep, tail)\n\
+"S.rpartition(sep) -> (tail, sep, head)\n\
\n\
Searches for the separator sep in S, starting at the end of S, and returns\n\
the part before it, the separator itself, and the part after it. If the\n\
-separator is not found, returns S and two empty strings.");
+separator is not found, returns two empty strings and S.");
static PyObject *
string_rpartition(PyStringObject *self, PyObject *sep_obj)
@@ -4136,7 +4150,8 @@ formatfloat(char *buf, size_t buflen, int flags,
double x;
x = PyFloat_AsDouble(v);
if (x == -1.0 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "float argument required");
+ PyErr_Format(PyExc_TypeError, "float argument required, "
+ "not %.200s", v->ob_type->tp_name);
return -1;
}
if (prec < 0)
@@ -4237,7 +4252,7 @@ _PyString_FormatLong(PyObject *val, int flags, int prec, int type,
return NULL;
}
llen = PyString_Size(result);
- if (llen > PY_SSIZE_T_MAX) {
+ if (llen > INT_MAX) {
PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong");
return NULL;
}
@@ -4331,7 +4346,8 @@ formatint(char *buf, size_t buflen, int flags,
x = PyInt_AsLong(v);
if (x == -1 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "int argument required");
+ PyErr_Format(PyExc_TypeError, "int argument required, not %.200s",
+ v->ob_type->tp_name);
return -1;
}
if (x < 0 && type == 'u') {
@@ -4726,9 +4742,10 @@ PyString_Format(PyObject *format, PyObject *args)
default:
PyErr_Format(PyExc_ValueError,
"unsupported format character '%c' (0x%x) "
- "at index %i",
+ "at index %zd",
c, c,
- (int)(fmt - 1 - PyString_AsString(format)));
+ (Py_ssize_t)(fmt - 1 -
+ PyString_AsString(format)));
goto error;
}
if (sign) {
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 6f3711f..c85b35a 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -620,8 +620,9 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
}
}
else {
- PyErr_SetString(PyExc_TypeError,
- "tuple indices must be integers");
+ PyErr_Format(PyExc_TypeError,
+ "tuple indices must be integers, not %.200s",
+ item->ob_type->tp_name);
return NULL;
}
}
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index ea1d1a2..1bef208 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -98,7 +98,7 @@ type_module(PyTypeObject *type, void *context)
s = strrchr(type->tp_name, '.');
if (s != NULL)
return PyString_FromStringAndSize(
- type->tp_name, (int)(s - type->tp_name));
+ type->tp_name, (Py_ssize_t)(s - type->tp_name));
return PyString_FromString("__builtin__");
}
}
@@ -3644,7 +3644,7 @@ hackcheck(PyObject *self, setattrofunc func, char *what)
while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
type = type->tp_base;
/* If type is NULL now, this is a really weird type.
- In the same of backwards compatibility (?), just shut up. */
+ In the spirit of backwards compatibility (?), just shut up. */
if (type && type->tp_setattro != func) {
PyErr_Format(PyExc_TypeError,
"can't apply this %s to %s object",
@@ -3861,7 +3861,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))
staticbase = staticbase->tp_base;
/* If staticbase is NULL now, it is a really weird type.
- In the same of backwards compatibility (?), just shut up. */
+ In the spirit of backwards compatibility (?), just shut up. */
if (staticbase && staticbase->tp_new != type->tp_new) {
PyErr_Format(PyExc_TypeError,
"%s.__new__(%s) is not safe, use %s.__new__()",
@@ -4017,19 +4017,10 @@ slot_sq_length(PyObject *self)
return -1;
len = PyInt_AsSsize_t(res);
Py_DECREF(res);
- if (len == -1 && PyErr_Occurred())
- return -1;
-#if SIZEOF_SIZE_T < SIZEOF_INT
- /* Overflow check -- range of PyInt is more than C ssize_t */
- if (len != (int)len) {
- PyErr_SetString(PyExc_OverflowError,
- "__len__() should return 0 <= outcome < 2**31");
- return -1;
- }
-#endif
if (len < 0) {
- PyErr_SetString(PyExc_ValueError,
- "__len__() should return >= 0");
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_ValueError,
+ "__len__() should return >= 0");
return -1;
}
return len;
@@ -5583,6 +5574,8 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *obj = NULL;
PyTypeObject *obj_type = NULL;
+ if (!_PyArg_NoKeywords("super", kwds))
+ return -1;
if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj))
return -1;
if (obj == Py_None)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 92301c0..bde3454 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2040,7 +2040,32 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
static const char *hexdigit = "0123456789abcdef";
- repr = PyString_FromStringAndSize(NULL, 2 + 6*size + 1);
+ /* XXX(nnorwitz): rather than over-allocating, it would be
+ better to choose a different scheme. Perhaps scan the
+ first N-chars of the string and allocate based on that size.
+ */
+ /* Initial allocation is based on the longest-possible unichr
+ escape.
+
+ In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
+ unichr, so in this case it's the longest unichr escape. In
+ narrow (UTF-16) builds this is five chars per source unichr
+ since there are two unichrs in the surrogate pair, so in narrow
+ (UTF-16) builds it's not the longest unichr escape.
+
+ In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
+ so in the narrow (UTF-16) build case it's the longest unichr
+ escape.
+ */
+
+ repr = PyString_FromStringAndSize(NULL,
+ 2
+#ifdef Py_UNICODE_WIDE
+ + 10*size
+#else
+ + 6*size
+#endif
+ + 1);
if (repr == NULL)
return NULL;
@@ -2065,15 +2090,6 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
#ifdef Py_UNICODE_WIDE
/* Map 21-bit characters to '\U00xxxxxx' */
else if (ch >= 0x10000) {
- Py_ssize_t offset = p - PyString_AS_STRING(repr);
-
- /* Resize the string if necessary */
- if (offset + 12 > PyString_GET_SIZE(repr)) {
- if (_PyString_Resize(&repr, PyString_GET_SIZE(repr) + 100))
- return NULL;
- p = PyString_AS_STRING(repr) + offset;
- }
-
*p++ = '\\';
*p++ = 'U';
*p++ = hexdigit[(ch >> 28) & 0x0000000F];
@@ -2086,8 +2102,8 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
*p++ = hexdigit[ch & 0x0000000F];
continue;
}
-#endif
- /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */
+#else
+ /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
else if (ch >= 0xD800 && ch < 0xDC00) {
Py_UNICODE ch2;
Py_UCS4 ucs;
@@ -2112,6 +2128,7 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
s--;
size++;
}
+#endif
/* Map 16-bit characters to '\uxxxx' */
if (ch >= 256) {
@@ -2367,6 +2384,7 @@ PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s,
Py_UNICODE unimax = PyUnicode_GetMax();
#endif
+ /* XXX overflow detection missing */
v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE);
if (v == NULL)
goto onError;
@@ -3153,6 +3171,7 @@ PyObject *PyUnicode_DecodeCharmap(const char *s,
Py_ssize_t needed = (targetsize - extrachars) + \
(targetsize << 2);
extrachars += needed;
+ /* XXX overflow detection missing */
if (_PyUnicode_Resize(&v,
PyUnicode_GET_SIZE(v) + needed) < 0) {
Py_DECREF(x);
@@ -6695,11 +6714,11 @@ unicode_partition(PyUnicodeObject *self, PyObject *separator)
}
PyDoc_STRVAR(rpartition__doc__,
-"S.rpartition(sep) -> (head, sep, tail)\n\
+"S.rpartition(sep) -> (tail, sep, head)\n\
\n\
Searches for the separator sep in S, starting at the end of S, and returns\n\
the part before it, the separator itself, and the part after it. If the\n\
-separator is not found, returns S and two empty strings.");
+separator is not found, returns two empty strings and S.");
static PyObject*
unicode_rpartition(PyUnicodeObject *self, PyObject *separator)
@@ -7744,10 +7763,11 @@ PyObject *PyUnicode_Format(PyObject *format,
default:
PyErr_Format(PyExc_ValueError,
"unsupported format character '%c' (0x%x) "
- "at index %i",
+ "at index %zd",
(31<=c && c<=126) ? (char)c : '?',
(int)c,
- (int)(fmt -1 - PyUnicode_AS_UNICODE(uformat)));
+ (Py_ssize_t)(fmt - 1 -
+ PyUnicode_AS_UNICODE(uformat)));
goto onError;
}
if (sign) {