give TypeError when trying to set T_STRING_INPLACE

This commit is contained in:
Benjamin Peterson 2010-04-03 01:28:57 +00:00
parent 931190b4f5
commit 1c7c11ef61
4 changed files with 27 additions and 5 deletions

View File

@ -9,7 +9,7 @@ import unittest
from test import test_support from test import test_support
ts=test_structmembersType(False, 1, 2, 3, 4, 5, 6, 7, 8, ts=test_structmembersType(False, 1, 2, 3, 4, 5, 6, 7, 8,
9.99999, 10.1010101010) 9.99999, 10.1010101010, "hi")
class ReadWriteTests(unittest.TestCase): class ReadWriteTests(unittest.TestCase):
@ -68,6 +68,11 @@ class ReadWriteTests(unittest.TestCase):
ts.T_ULONGLONG = 4 ts.T_ULONGLONG = 4
self.assertEquals(ts.T_ULONGLONG, 4) self.assertEquals(ts.T_ULONGLONG, 4)
def test_inplace_string(self):
self.assertEquals(ts.T_STRING_INPLACE, "hi")
self.assertRaises(TypeError, setattr, ts, "T_STRING_INPLACE", "s")
self.assertRaises(TypeError, delattr, ts, "T_STRING_INPLACE")
class TestWarnings(unittest.TestCase): class TestWarnings(unittest.TestCase):

View File

@ -12,6 +12,8 @@ What's New in Python 2.7 beta 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Raise a TypeError when trying to delete a T_STRING_INPLACE struct member.
- Issue #7994: Issue a PendingDeprecationWarning if object.__format__ - Issue #7994: Issue a PendingDeprecationWarning if object.__format__
is called with a non-empty format string. This is an effort to is called with a non-empty format string. This is an effort to
future-proof user code. If a derived class does not currently future-proof user code. If a derived class does not currently

View File

@ -1712,6 +1712,7 @@ typedef struct {
unsigned long ulong_member; unsigned long ulong_member;
float float_member; float float_member;
double double_member; double double_member;
char inplace_member[5];
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
PY_LONG_LONG longlong_member; PY_LONG_LONG longlong_member;
unsigned PY_LONG_LONG ulonglong_member; unsigned PY_LONG_LONG ulonglong_member;
@ -1735,6 +1736,7 @@ static struct PyMemberDef test_members[] = {
{"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
{"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
{"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
{"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
@ -1749,17 +1751,19 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
static char *keywords[] = { static char *keywords[] = {
"T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT",
"T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_INT", "T_UINT", "T_LONG", "T_ULONG",
"T_FLOAT", "T_DOUBLE", "T_FLOAT", "T_DOUBLE", "T_INPLACE_STRING",
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
"T_LONGLONG", "T_ULONGLONG", "T_LONGLONG", "T_ULONGLONG",
#endif #endif
NULL}; NULL};
static char *fmt = "|bbBhHiIlkfd" static char *fmt = "|bbBhHiIlkfds#"
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
"LK" "LK"
#endif #endif
; ;
test_structmembers *ob; test_structmembers *ob;
const char *s;
Py_ssize_t string_len = 0;
ob = PyObject_New(test_structmembers, type); ob = PyObject_New(test_structmembers, type);
if (ob == NULL) if (ob == NULL)
return NULL; return NULL;
@ -1775,7 +1779,8 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
&ob->structmembers.long_member, &ob->structmembers.long_member,
&ob->structmembers.ulong_member, &ob->structmembers.ulong_member,
&ob->structmembers.float_member, &ob->structmembers.float_member,
&ob->structmembers.double_member &ob->structmembers.double_member,
&s, &string_len
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
, &ob->structmembers.longlong_member, , &ob->structmembers.longlong_member,
&ob->structmembers.ulonglong_member &ob->structmembers.ulonglong_member
@ -1784,6 +1789,12 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Py_DECREF(ob); Py_DECREF(ob);
return NULL; return NULL;
} }
if (string_len > 5) {
Py_DECREF(ob);
PyErr_SetString(PyExc_ValueError, "string too long");
return NULL;
}
strcpy(ob->structmembers.inplace_member, s);
return (PyObject *)ob; return (PyObject *)ob;
} }

View File

@ -172,7 +172,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
addr += l->offset; addr += l->offset;
if ((l->flags & READONLY) || l->type == T_STRING) if ((l->flags & READONLY))
{ {
PyErr_SetString(PyExc_TypeError, "readonly attribute"); PyErr_SetString(PyExc_TypeError, "readonly attribute");
return -1; return -1;
@ -329,6 +329,10 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
return -1; return -1;
} }
break; break;
case T_STRING:
case T_STRING_INPLACE:
PyErr_SetString(PyExc_TypeError, "readonly attribute");
return -1;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case T_LONGLONG:{ case T_LONGLONG:{
PY_LONG_LONG value; PY_LONG_LONG value;