Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3)

Delta Between Two Patch Sets: Modules/_ctypes/stgdict.c

Issue 10744: ctypes arrays have incorrect buffer information (PEP-3118)
Left Patch Set: Created 5 years, 9 months ago
Right Patch Set: Created 5 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Modules/_ctypes/ctypes.h ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
4
5 #include "Python.h" 1 #include "Python.h"
6 #include <ffi.h> 2 #include <ffi.h>
7 #ifdef MS_WIN32 3 #ifdef MS_WIN32
8 #include <windows.h> 4 #include <windows.h>
9 #include <malloc.h> 5 #include <malloc.h>
10 #endif 6 #endif
11 #include "ctypes.h" 7 #include "ctypes.h"
12 8
13 /******************************************************************/ 9 /******************************************************************/
14 /* 10 /*
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 104
109 PyTypeObject PyCStgDict_Type = { 105 PyTypeObject PyCStgDict_Type = {
110 PyVarObject_HEAD_INIT(NULL, 0) 106 PyVarObject_HEAD_INIT(NULL, 0)
111 "StgDict", 107 "StgDict",
112 sizeof(StgDictObject), 108 sizeof(StgDictObject),
113 0, 109 0,
114 (destructor)PyCStgDict_dealloc, /* tp_dealloc */ 110 (destructor)PyCStgDict_dealloc, /* tp_dealloc */
115 0, /* tp_print */ 111 0, /* tp_print */
116 0, /* tp_getattr */ 112 0, /* tp_getattr */
117 0, /* tp_setattr */ 113 0, /* tp_setattr */
118 0, /* tp_compare */ 114 0, /* tp_reserved */
119 0, /* tp_repr */ 115 0, /* tp_repr */
120 0, /* tp_as_number */ 116 0, /* tp_as_number */
121 0, /* tp_as_sequence */ 117 0, /* tp_as_sequence */
122 0, /* tp_as_mapping */ 118 0, /* tp_as_mapping */
123 0, /* tp_hash */ 119 0, /* tp_hash */
124 0, /* tp_call */ 120 0, /* tp_call */
125 0, /* tp_str */ 121 0, /* tp_str */
126 0, /* tp_getattro */ 122 0, /* tp_getattro */
127 0, /* tp_setattro */ 123 0, /* tp_setattro */
128 0, /* tp_as_buffer */ 124 0, /* tp_as_buffer */
(...skipping 21 matching lines...) Expand all
150 146
151 /* May return NULL, but does not set an exception! */ 147 /* May return NULL, but does not set an exception! */
152 StgDictObject * 148 StgDictObject *
153 PyType_stgdict(PyObject *obj) 149 PyType_stgdict(PyObject *obj)
154 { 150 {
155 PyTypeObject *type; 151 PyTypeObject *type;
156 152
157 if (!PyType_Check(obj)) 153 if (!PyType_Check(obj))
158 return NULL; 154 return NULL;
159 type = (PyTypeObject *)obj; 155 type = (PyTypeObject *)obj;
160 if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
161 return NULL;
162 if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) 156 if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
163 return NULL; 157 return NULL;
164 return (StgDictObject *)type->tp_dict; 158 return (StgDictObject *)type->tp_dict;
165 } 159 }
166 160
167 /* May return NULL, but does not set an exception! */ 161 /* May return NULL, but does not set an exception! */
168 /* 162 /*
169 This function should be as fast as possible, so we don't call PyType_stgdict 163 This function should be as fast as possible, so we don't call PyType_stgdict
170 above but inline the code, and avoid the PyType_Check(). 164 above but inline the code, and avoid the PyType_Check().
171 */ 165 */
172 StgDictObject * 166 StgDictObject *
173 PyObject_stgdict(PyObject *self) 167 PyObject_stgdict(PyObject *self)
174 { 168 {
175 PyTypeObject *type = self->ob_type; 169 PyTypeObject *type = self->ob_type;
176 if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
177 return NULL;
178 if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) 170 if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
179 return NULL; 171 return NULL;
180 return (StgDictObject *)type->tp_dict; 172 return (StgDictObject *)type->tp_dict;
181 } 173 }
182 174
183 /* descr is the descriptor for a field marked as anonymous. Get all the 175 /* descr is the descriptor for a field marked as anonymous. Get all the
184 _fields_ descriptors from descr->proto, create new descriptors with offset 176 _fields_ descriptors from descr->proto, create new descriptors with offset
185 and index adjusted, and stuff them into type. 177 and index adjusted, and stuff them into type.
186 */ 178 */
187 static int 179 static int
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; 328 big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1;
337 #else 329 #else
338 big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0; 330 big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0;
339 #endif 331 #endif
340 332
341 use_broken_old_ctypes_semantics = \ 333 use_broken_old_ctypes_semantics = \
342 PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics _"); 334 PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics _");
343 335
344 isPacked = PyObject_GetAttrString(type, "_pack_"); 336 isPacked = PyObject_GetAttrString(type, "_pack_");
345 if (isPacked) { 337 if (isPacked) {
346 pack = _PyInt_AsInt(isPacked); 338 pack = _PyLong_AsInt(isPacked);
347 if (pack < 0 || PyErr_Occurred()) { 339 if (pack < 0 || PyErr_Occurred()) {
348 Py_XDECREF(isPacked); 340 Py_XDECREF(isPacked);
349 PyErr_SetString(PyExc_ValueError, 341 PyErr_SetString(PyExc_ValueError,
350 "_pack_ must be a non-negative integer"); 342 "_pack_ must be a non-negative integer");
351 return -1; 343 return -1;
352 } 344 }
353 Py_DECREF(isPacked); 345 Py_DECREF(isPacked);
354 } else 346 } else
355 PyErr_Clear(); 347 PyErr_Clear();
356 348
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 410
419 assert(stgdict->format == NULL); 411 assert(stgdict->format == NULL);
420 if (isStruct && !isPacked) { 412 if (isStruct && !isPacked) {
421 stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); 413 stgdict->format = _ctypes_alloc_format_string(NULL, "T{");
422 } else { 414 } else {
423 /* PEP3118 doesn't support union, or packed structures (well, 415 /* PEP3118 doesn't support union, or packed structures (well,
424 only standard packing, but we dont support the pep for 416 only standard packing, but we dont support the pep for
425 that). Use 'B' for bytes. */ 417 that). Use 'B' for bytes. */
426 stgdict->format = _ctypes_alloc_format_string(NULL, "B"); 418 stgdict->format = _ctypes_alloc_format_string(NULL, "B");
427 } 419 }
420 if (stgdict->format == NULL)
421 return -1;
428 422
429 #define realdict ((PyObject *)&stgdict->dict) 423 #define realdict ((PyObject *)&stgdict->dict)
430 for (i = 0; i < len; ++i) { 424 for (i = 0; i < len; ++i) {
431 PyObject *name = NULL, *desc = NULL; 425 PyObject *name = NULL, *desc = NULL;
432 PyObject *pair = PySequence_GetItem(fields, i); 426 PyObject *pair = PySequence_GetItem(fields, i);
433 PyObject *prop; 427 PyObject *prop;
434 StgDictObject *dict; 428 StgDictObject *dict;
435 int bitsize = 0; 429 int bitsize = 0;
436 430
437 if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) { 431 if (!pair || !PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) {
438 PyErr_SetString(PyExc_AttributeError, 432 PyErr_SetString(PyExc_TypeError,
439 "'_fields_' must be a sequence of pairs"); 433 "'_fields_' must be a sequence of (name, C type) pai rs");
440 Py_XDECREF(pair); 434 Py_XDECREF(pair);
441 return -1; 435 return -1;
442 } 436 }
443 dict = PyType_stgdict(desc); 437 dict = PyType_stgdict(desc);
444 if (dict == NULL) { 438 if (dict == NULL) {
445 Py_DECREF(pair); 439 Py_DECREF(pair);
446 PyErr_Format(PyExc_TypeError, 440 PyErr_Format(PyExc_TypeError,
447 #if (PY_VERSION_HEX < 0x02050000)
448 "second item in _fields_ tuple (index %d) must be a C t ype",
449 #else
450 "second item in _fields_ tuple (index %zd) must be a C type", 441 "second item in _fields_ tuple (index %zd) must be a C type",
451 #endif
452 i); 442 i);
453 return -1; 443 return -1;
454 } 444 }
455 stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointe r; 445 stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointe r;
456 if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) 446 if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
457 stgdict->flags |= TYPEFLAG_HASPOINTER; 447 stgdict->flags |= TYPEFLAG_HASPOINTER;
458 dict->flags |= DICTFLAG_FINAL; /* mark field type final */ 448 dict->flags |= DICTFLAG_FINAL; /* mark field type final */
459 if (PyTuple_Size(pair) == 3) { /* bits specified */ 449 if (PyTuple_Size(pair) == 3) { /* bits specified */
460 switch(dict->ffi_type_pointer.type) { 450 switch(dict->ffi_type_pointer.type) {
461 case FFI_TYPE_UINT8: 451 case FFI_TYPE_UINT8:
(...skipping 21 matching lines...) Expand all
483 return -1; 473 return -1;
484 } 474 }
485 if (bitsize <= 0 || bitsize > dict->size * 8) { 475 if (bitsize <= 0 || bitsize > dict->size * 8) {
486 PyErr_SetString(PyExc_ValueError, 476 PyErr_SetString(PyExc_ValueError,
487 "number of bits invalid for bit field"); 477 "number of bits invalid for bit field");
488 Py_DECREF(pair); 478 Py_DECREF(pair);
489 return -1; 479 return -1;
490 } 480 }
491 } else 481 } else
492 bitsize = 0; 482 bitsize = 0;
483
493 if (isStruct && !isPacked) { 484 if (isStruct && !isPacked) {
494 char *fieldfmt = dict->format ? dict->format : "B"; 485 char *fieldfmt = dict->format ? dict->format : "B";
495 char *fieldname = PyString_AsString(name); 486 char *fieldname = _PyUnicode_AsString(name);
496 char *ptr; 487 char *ptr;
497 Py_ssize_t len; 488 Py_ssize_t len;
498 char *buf; 489 char *buf;
499 490
500 if (fieldname == NULL) 491 if (fieldname == NULL)
501 { 492 {
502 PyErr_Format(PyExc_TypeError,
503 "structure field name must be string not %s",
504 name->ob_type->tp_name);
505
506 Py_DECREF(pair); 493 Py_DECREF(pair);
507 return -1; 494 return -1;
508 } 495 }
509 496
510 len = strlen(fieldname) + strlen(fieldfmt); 497 len = strlen(fieldname) + strlen(fieldfmt);
511 498
512 buf = PyMem_Malloc(len + 2 + 1); 499 buf = PyMem_Malloc(len + 2 + 1);
513 if (buf == NULL) { 500 if (buf == NULL) {
514 Py_DECREF(pair); 501 Py_DECREF(pair);
515 PyErr_NoMemory(); 502 PyErr_NoMemory();
516 return -1; 503 return -1;
517 } 504 }
518 sprintf(buf, "%s:%s:", fieldfmt, fieldname); 505 sprintf(buf, "%s:%s:", fieldfmt, fieldname);
519 506
520 ptr = stgdict->format; 507 ptr = stgdict->format;
521 if (dict->shape != NULL) { 508 if (dict->shape != NULL) {
522 stgdict->format = _ctypes_alloc_format_string_with_shape( 509 stgdict->format = _ctypes_alloc_format_string_with_shape(
523 dict->ndim, dict->shape, stgdict->format, buf); 510 dict->ndim, dict->shape, stgdict->format, buf);
524 } else { 511 } else {
525 stgdict->format = _ctypes_alloc_format_string(stgdict->format, b uf); 512 stgdict->format = _ctypes_alloc_format_string(stgdict->format, b uf);
526 } 513 }
527 PyMem_Free(ptr); 514 PyMem_Free(ptr);
528 PyMem_Free(buf); 515 PyMem_Free(buf);
529 516
530 if (stgdict->format == NULL) { 517 if (stgdict->format == NULL) {
531 Py_DECREF(pair); 518 Py_DECREF(pair);
532 return -1; 519 return -1;
533 } 520 }
534 } 521 }
522
535 if (isStruct) { 523 if (isStruct) {
536 prop = PyCField_FromDesc(desc, i, 524 prop = PyCField_FromDesc(desc, i,
537 &field_size, bitsize, &bitofs, 525 &field_size, bitsize, &bitofs,
538 &size, &offset, &align, 526 &size, &offset, &align,
539 pack, big_endian); 527 pack, big_endian);
540 } else /* union */ { 528 } else /* union */ {
541 size = 0; 529 size = 0;
542 offset = 0; 530 offset = 0;
543 align = 0; 531 align = 0;
544 prop = PyCField_FromDesc(desc, i, 532 prop = PyCField_FromDesc(desc, i,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 have been set until now. */ 578 have been set until now. */
591 if (stgdict->flags & DICTFLAG_FINAL) { 579 if (stgdict->flags & DICTFLAG_FINAL) {
592 PyErr_SetString(PyExc_AttributeError, 580 PyErr_SetString(PyExc_AttributeError,
593 "Structure or union cannot contain itself"); 581 "Structure or union cannot contain itself");
594 return -1; 582 return -1;
595 } 583 }
596 stgdict->flags |= DICTFLAG_FINAL; 584 stgdict->flags |= DICTFLAG_FINAL;
597 585
598 return MakeAnonFields(type); 586 return MakeAnonFields(type);
599 } 587 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+