| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -816,6 +816,18 @@ def test_endian_table_init_subinterpreters(self): | |||
| 816 | 816 | results = executor.map(exec, [code] * 5) | |
| 817 | 817 | self.assertListEqual(list(results), [None] * 5) | |
| 818 | 818 | ||
| 819 | + def test_operations_on_half_initialized_Struct(self): | ||
| 820 | + S = struct.Struct.__new__(struct.Struct) | ||
| 821 | + | ||
| 822 | + spam = array.array('b', b' ') | ||
| 823 | + self.assertRaises(RuntimeError, S.iter_unpack, spam) | ||
| 824 | + self.assertRaises(RuntimeError, S.pack, 1) | ||
| 825 | + self.assertRaises(RuntimeError, S.pack_into, spam, 1) | ||
| 826 | + self.assertRaises(RuntimeError, S.unpack, spam) | ||
| 827 | + self.assertRaises(RuntimeError, S.unpack_from, spam) | ||
| 828 | + self.assertRaises(RuntimeError, getattr, S, 'format') | ||
| 829 | + self.assertEqual(S.size, -1) | ||
| 830 | + | ||
| 819 | 831 | ||
| 820 | 832 | class UnpackIteratorTest(unittest.TestCase): | |
| 821 | 833 | """ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Raise :exc:`RuntimeError`'s when user attempts to call methods on | ||
| 2 | + half-initialized :class:`~struct.Struct` objects, For example, created by | ||
| 3 | + ``Struct.__new__(Struct)``. Patch by Sergey B Kirpichev. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1698,8 +1698,6 @@ prepare_s(PyStructObject *self) | |||
| 1698 | 1698 | return -1; | |
| 1699 | 1699 | } | |
| 1700 | 1700 | ||
| 1701 | - self->s_size = size; | ||
| 1702 | - self->s_len = len; | ||
| 1703 | 1701 | codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode)); | |
| 1704 | 1702 | if (codes == NULL) { | |
| 1705 | 1703 | PyErr_NoMemory(); | |
@@ -1709,6 +1707,8 @@ prepare_s(PyStructObject *self) | |||
| 1709 | 1707 | if (self->s_codes != NULL) | |
| 1710 | 1708 | PyMem_Free(self->s_codes); | |
| 1711 | 1709 | self->s_codes = codes; | |
| 1710 | + self->s_size = size; | ||
| 1711 | + self->s_len = len; | ||
| 1712 | 1712 | ||
| 1713 | 1713 | s = fmt; | |
| 1714 | 1714 | size = 0; | |
@@ -1897,6 +1897,14 @@ s_unpack_internal(PyStructObject *soself, const char *startfrom, | |||
| 1897 | 1897 | return NULL; | |
| 1898 | 1898 | } | |
| 1899 | 1899 | ||
| 1900 | + #define ENSURE_STRUCT_IS_READY(self) \ | ||
| 1901 | + do { \ | ||
| 1902 | + if (!(self)->s_codes) { \ | ||
| 1903 | + PyErr_SetString(PyExc_RuntimeError, \ | ||
| 1904 | + "Struct object is not initialized"); \ | ||
| 1905 | + return NULL; \ | ||
| 1906 | + } \ | ||
| 1907 | + } while (0); | ||
| 1900 | 1908 | ||
| 1901 | 1909 | /*[clinic input] | |
| 1902 | 1910 | Struct.unpack | |
@@ -1917,7 +1925,7 @@ Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer) | |||
| 1917 | 1925 | /*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ | |
| 1918 | 1926 | { | |
| 1919 | 1927 | _structmodulestate *state = get_struct_state_structinst(self); | |
| 1920 | - assert(self->s_codes != NULL); | ||
| 1928 | + ENSURE_STRUCT_IS_READY(self); | ||
| 1921 | 1929 | if (buffer->len != self->s_size) { | |
| 1922 | 1930 | PyErr_Format(state->StructError, | |
| 1923 | 1931 | "unpack requires a buffer of %zd bytes", | |
@@ -1949,7 +1957,7 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, | |||
| 1949 | 1957 | /*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ | |
| 1950 | 1958 | { | |
| 1951 | 1959 | _structmodulestate *state = get_struct_state_structinst(self); | |
| 1952 | - assert(self->s_codes != NULL); | ||
| 1960 | + ENSURE_STRUCT_IS_READY(self); | ||
| 1953 | 1961 | ||
| 1954 | 1962 | if (offset < 0) { | |
| 1955 | 1963 | if (offset + self->s_size > 0) { | |
@@ -2101,8 +2109,7 @@ Struct_iter_unpack_impl(PyStructObject *self, PyObject *buffer) | |||
| 2101 | 2109 | { | |
| 2102 | 2110 | _structmodulestate *state = get_struct_state_structinst(self); | |
| 2103 | 2111 | unpackiterobject *iter; | |
| 2104 | - | ||
| 2105 | - assert(self->s_codes != NULL); | ||
| 2112 | + ENSURE_STRUCT_IS_READY(self); | ||
| 2106 | 2113 | ||
| 2107 | 2114 | if (self->s_size == 0) { | |
| 2108 | 2115 | PyErr_Format(state->StructError, | |
@@ -2242,8 +2249,8 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |||
| 2242 | 2249 | ||
| 2243 | 2250 | /* Validate arguments. */ | |
| 2244 | 2251 | soself = PyStructObject_CAST(self); | |
| 2252 | + ENSURE_STRUCT_IS_READY(soself); | ||
| 2245 | 2253 | assert(PyStruct_Check(self, state)); | |
| 2246 | - assert(soself->s_codes != NULL); | ||
| 2247 | 2254 | if (nargs != soself->s_len) | |
| 2248 | 2255 | { | |
| 2249 | 2256 | PyErr_Format(state->StructError, | |
@@ -2285,8 +2292,8 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |||
| 2285 | 2292 | ||
| 2286 | 2293 | /* Validate arguments. +1 is for the first arg as buffer. */ | |
| 2287 | 2294 | soself = PyStructObject_CAST(self); | |
| 2295 | + ENSURE_STRUCT_IS_READY(soself); | ||
| 2288 | 2296 | assert(PyStruct_Check(self, state)); | |
| 2289 | - assert(soself->s_codes != NULL); | ||
| 2290 | 2297 | if (nargs != (soself->s_len + 2)) | |
| 2291 | 2298 | { | |
| 2292 | 2299 | if (nargs == 0) { | |
@@ -2373,6 +2380,7 @@ static PyObject * | |||
| 2373 | 2380 | s_get_format(PyObject *op, void *Py_UNUSED(closure)) | |
| 2374 | 2381 | { | |
| 2375 | 2382 | PyStructObject *self = PyStructObject_CAST(op); | |
| 2383 | + ENSURE_STRUCT_IS_READY(self); | ||
| 2376 | 2384 | return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format), | |
| 2377 | 2385 | PyBytes_GET_SIZE(self->s_format)); | |
| 2378 | 2386 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments