1 /* struct module -- pack values into and (out of) bytes objects */
2
3 /* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6 #define PY_SSIZE_T_CLEAN
7
8 #include "Python.h"
9 #include "structmember.h" // PyMemberDef
10 #include <ctype.h>
11
12 /*[clinic input]
13 class Struct "PyStructObject *" "&PyStructType"
14 [clinic start generated code]*/
15 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
16
17 typedef struct {
18 PyObject *PyStructType;
19 PyObject *unpackiter_type;
20 PyObject *StructError;
21 } _structmodulestate;
22
23 static inline _structmodulestate*
get_struct_state(PyObject * module)24 get_struct_state(PyObject *module)
25 {
26 void *state = PyModule_GetState(module);
27 assert(state != NULL);
28 return (_structmodulestate *)state;
29 }
30
31 static struct PyModuleDef _structmodule;
32
33 #define _structmodulestate_global get_struct_state(PyState_FindModule(&_structmodule))
34
35 /* The translation function for each format character is table driven */
36 typedef struct _formatdef {
37 char format;
38 Py_ssize_t size;
39 Py_ssize_t alignment;
40 PyObject* (*unpack)(const char *,
41 const struct _formatdef *);
42 int (*pack)(char *, PyObject *,
43 const struct _formatdef *);
44 } formatdef;
45
46 typedef struct _formatcode {
47 const struct _formatdef *fmtdef;
48 Py_ssize_t offset;
49 Py_ssize_t size;
50 Py_ssize_t repeat;
51 } formatcode;
52
53 /* Struct object interface */
54
55 typedef struct {
56 PyObject_HEAD
57 Py_ssize_t s_size;
58 Py_ssize_t s_len;
59 formatcode *s_codes;
60 PyObject *s_format;
61 PyObject *weakreflist; /* List of weak references */
62 } PyStructObject;
63
64
65 #define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
66 #define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
67
68
69 /* Define various structs to figure out the alignments of types */
70
71
72 typedef struct { char c; short x; } st_short;
73 typedef struct { char c; int x; } st_int;
74 typedef struct { char c; long x; } st_long;
75 typedef struct { char c; float x; } st_float;
76 typedef struct { char c; double x; } st_double;
77 typedef struct { char c; void *x; } st_void_p;
78 typedef struct { char c; size_t x; } st_size_t;
79 typedef struct { char c; _Bool x; } st_bool;
80
81 #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
82 #define INT_ALIGN (sizeof(st_int) - sizeof(int))
83 #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
84 #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
85 #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
86 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
87 #define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
88 #define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
89
90 /* We can't support q and Q in native mode unless the compiler does;
91 in std mode, they're 8 bytes on all platforms. */
92 typedef struct { char c; long long x; } s_long_long;
93 #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
94
95 #ifdef __powerc
96 #pragma options align=reset
97 #endif
98
99 /*[python input]
100 class cache_struct_converter(CConverter):
101 type = 'PyStructObject *'
102 converter = 'cache_struct_converter'
103 c_default = "NULL"
104
105 def cleanup(self):
106 return "Py_XDECREF(%s);\n" % self.name
107 [python start generated code]*/
108 /*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
109
110 static int cache_struct_converter(PyObject *, PyStructObject **);
111
112 #include "clinic/_struct.c.h"
113
114 /* Helper for integer format codes: converts an arbitrary Python object to a
115 PyLongObject if possible, otherwise fails. Caller should decref. */
116
117 static PyObject *
get_pylong(PyObject * v)118 get_pylong(PyObject *v)
119 {
120 assert(v != NULL);
121 if (!PyLong_Check(v)) {
122 /* Not an integer; try to use __index__ to convert. */
123 if (PyIndex_Check(v)) {
124 v = PyNumber_Index(v);
125 if (v == NULL)
126 return NULL;
127 }
128 else {
129 PyErr_SetString(_structmodulestate_global->StructError,
130 "required argument is not an integer");
131 return NULL;
132 }
133 }
134 else
135 Py_INCREF(v);
136
137 assert(PyLong_Check(v));
138 return v;
139 }
140
141 /* Helper routine to get a C long and raise the appropriate error if it isn't
142 one */
143
144 static int
get_long(PyObject * v,long * p)145 get_long(PyObject *v, long *p)
146 {
147 long x;
148
149 v = get_pylong(v);
150 if (v == NULL)
151 return -1;
152 assert(PyLong_Check(v));
153 x = PyLong_AsLong(v);
154 Py_DECREF(v);
155 if (x == (long)-1 && PyErr_Occurred()) {
156 if (PyErr_ExceptionMatches(PyExc_OverflowError))
157 PyErr_SetString(_structmodulestate_global->StructError,
158 "argument out of range");
159 return -1;
160 }
161 *p = x;
162 return 0;
163 }
164
165
166 /* Same, but handling unsigned long */
167
168 static int
get_ulong(PyObject * v,unsigned long * p)169 get_ulong(PyObject *v, unsigned long *p)
170 {
171 unsigned long x;
172
173 v = get_pylong(v);
174 if (v == NULL)
175 return -1;
176 assert(PyLong_Check(v));
177 x = PyLong_AsUnsignedLong(v);
178 Py_DECREF(v);
179 if (x == (unsigned long)-1 && PyErr_Occurred()) {
180 if (PyErr_ExceptionMatches(PyExc_OverflowError))
181 PyErr_SetString(_structmodulestate_global->StructError,
182 "argument out of range");
183 return -1;
184 }
185 *p = x;
186 return 0;
187 }
188
189 /* Same, but handling native long long. */
190
191 static int
get_longlong(PyObject * v,long long * p)192 get_longlong(PyObject *v, long long *p)
193 {
194 long long x;
195
196 v = get_pylong(v);
197 if (v == NULL)
198 return -1;
199 assert(PyLong_Check(v));
200 x = PyLong_AsLongLong(v);
201 Py_DECREF(v);
202 if (x == (long long)-1 && PyErr_Occurred()) {
203 if (PyErr_ExceptionMatches(PyExc_OverflowError))
204 PyErr_SetString(_structmodulestate_global->StructError,
205 "argument out of range");
206 return -1;
207 }
208 *p = x;
209 return 0;
210 }
211
212 /* Same, but handling native unsigned long long. */
213
214 static int
get_ulonglong(PyObject * v,unsigned long long * p)215 get_ulonglong(PyObject *v, unsigned long long *p)
216 {
217 unsigned long long x;
218
219 v = get_pylong(v);
220 if (v == NULL)
221 return -1;
222 assert(PyLong_Check(v));
223 x = PyLong_AsUnsignedLongLong(v);
224 Py_DECREF(v);
225 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
226 if (PyErr_ExceptionMatches(PyExc_OverflowError))
227 PyErr_SetString(_structmodulestate_global->StructError,
228 "argument out of range");
229 return -1;
230 }
231 *p = x;
232 return 0;
233 }
234
235 /* Same, but handling Py_ssize_t */
236
237 static int
get_ssize_t(PyObject * v,Py_ssize_t * p)238 get_ssize_t(PyObject *v, Py_ssize_t *p)
239 {
240 Py_ssize_t x;
241
242 v = get_pylong(v);
243 if (v == NULL)
244 return -1;
245 assert(PyLong_Check(v));
246 x = PyLong_AsSsize_t(v);
247 Py_DECREF(v);
248 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
249 if (PyErr_ExceptionMatches(PyExc_OverflowError))
250 PyErr_SetString(_structmodulestate_global->StructError,
251 "argument out of range");
252 return -1;
253 }
254 *p = x;
255 return 0;
256 }
257
258 /* Same, but handling size_t */
259
260 static int
get_size_t(PyObject * v,size_t * p)261 get_size_t(PyObject *v, size_t *p)
262 {
263 size_t x;
264
265 v = get_pylong(v);
266 if (v == NULL)
267 return -1;
268 assert(PyLong_Check(v));
269 x = PyLong_AsSize_t(v);
270 Py_DECREF(v);
271 if (x == (size_t)-1 && PyErr_Occurred()) {
272 if (PyErr_ExceptionMatches(PyExc_OverflowError))
273 PyErr_SetString(_structmodulestate_global->StructError,
274 "argument out of range");
275 return -1;
276 }
277 *p = x;
278 return 0;
279 }
280
281
282 #define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
283
284
285 /* Floating point helpers */
286
287 static PyObject *
unpack_halffloat(const char * p,int le)288 unpack_halffloat(const char *p, /* start of 2-byte string */
289 int le) /* true for little-endian, false for big-endian */
290 {
291 double x;
292
293 x = _PyFloat_Unpack2((unsigned char *)p, le);
294 if (x == -1.0 && PyErr_Occurred()) {
295 return NULL;
296 }
297 return PyFloat_FromDouble(x);
298 }
299
300 static int
pack_halffloat(char * p,PyObject * v,int le)301 pack_halffloat(char *p, /* start of 2-byte string */
302 PyObject *v, /* value to pack */
303 int le) /* true for little-endian, false for big-endian */
304 {
305 double x = PyFloat_AsDouble(v);
306 if (x == -1.0 && PyErr_Occurred()) {
307 PyErr_SetString(_structmodulestate_global->StructError,
308 "required argument is not a float");
309 return -1;
310 }
311 return _PyFloat_Pack2(x, (unsigned char *)p, le);
312 }
313
314 static PyObject *
unpack_float(const char * p,int le)315 unpack_float(const char *p, /* start of 4-byte string */
316 int le) /* true for little-endian, false for big-endian */
317 {
318 double x;
319
320 x = _PyFloat_Unpack4((unsigned char *)p, le);
321 if (x == -1.0 && PyErr_Occurred())
322 return NULL;
323 return PyFloat_FromDouble(x);
324 }
325
326 static PyObject *
unpack_double(const char * p,int le)327 unpack_double(const char *p, /* start of 8-byte string */
328 int le) /* true for little-endian, false for big-endian */
329 {
330 double x;
331
332 x = _PyFloat_Unpack8((unsigned char *)p, le);
333 if (x == -1.0 && PyErr_Occurred())
334 return NULL;
335 return PyFloat_FromDouble(x);
336 }
337
338 /* Helper to format the range error exceptions */
339 static int
_range_error(const formatdef * f,int is_unsigned)340 _range_error(const formatdef *f, int is_unsigned)
341 {
342 /* ulargest is the largest unsigned value with f->size bytes.
343 * Note that the simpler:
344 * ((size_t)1 << (f->size * 8)) - 1
345 * doesn't work when f->size == sizeof(size_t) because C doesn't
346 * define what happens when a left shift count is >= the number of
347 * bits in the integer being shifted; e.g., on some boxes it doesn't
348 * shift at all when they're equal.
349 */
350 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
351 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
352 if (is_unsigned)
353 PyErr_Format(_structmodulestate_global->StructError,
354 "'%c' format requires 0 <= number <= %zu",
355 f->format,
356 ulargest);
357 else {
358 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
359 PyErr_Format(_structmodulestate_global->StructError,
360 "'%c' format requires %zd <= number <= %zd",
361 f->format,
362 ~ largest,
363 largest);
364 }
365
366 return -1;
367 }
368
369
370
371 /* A large number of small routines follow, with names of the form
372
373 [bln][up]_TYPE
374
375 [bln] distinguishes among big-endian, little-endian and native.
376 [pu] distinguishes between pack (to struct) and unpack (from struct).
377 TYPE is one of char, byte, ubyte, etc.
378 */
379
380 /* Native mode routines. ****************************************************/
381 /* NOTE:
382 In all n[up]_<type> routines handling types larger than 1 byte, there is
383 *no* guarantee that the p pointer is properly aligned for each type,
384 therefore memcpy is called. An intermediate variable is used to
385 compensate for big-endian architectures.
386 Normally both the intermediate variable and the memcpy call will be
387 skipped by C optimisation in little-endian architectures (gcc >= 2.91
388 does this). */
389
390 static PyObject *
nu_char(const char * p,const formatdef * f)391 nu_char(const char *p, const formatdef *f)
392 {
393 return PyBytes_FromStringAndSize(p, 1);
394 }
395
396 static PyObject *
nu_byte(const char * p,const formatdef * f)397 nu_byte(const char *p, const formatdef *f)
398 {
399 return PyLong_FromLong((long) *(signed char *)p);
400 }
401
402 static PyObject *
nu_ubyte(const char * p,const formatdef * f)403 nu_ubyte(const char *p, const formatdef *f)
404 {
405 return PyLong_FromLong((long) *(unsigned char *)p);
406 }
407
408 static PyObject *
nu_short(const char * p,const formatdef * f)409 nu_short(const char *p, const formatdef *f)
410 {
411 short x;
412 memcpy((char *)&x, p, sizeof x);
413 return PyLong_FromLong((long)x);
414 }
415
416 static PyObject *
nu_ushort(const char * p,const formatdef * f)417 nu_ushort(const char *p, const formatdef *f)
418 {
419 unsigned short x;
420 memcpy((char *)&x, p, sizeof x);
421 return PyLong_FromLong((long)x);
422 }
423
424 static PyObject *
nu_int(const char * p,const formatdef * f)425 nu_int(const char *p, const formatdef *f)
426 {
427 int x;
428 memcpy((char *)&x, p, sizeof x);
429 return PyLong_FromLong((long)x);
430 }
431
432 static PyObject *
nu_uint(const char * p,const formatdef * f)433 nu_uint(const char *p, const formatdef *f)
434 {
435 unsigned int x;
436 memcpy((char *)&x, p, sizeof x);
437 return PyLong_FromUnsignedLong((unsigned long)x);
438 }
439
440 static PyObject *
nu_long(const char * p,const formatdef * f)441 nu_long(const char *p, const formatdef *f)
442 {
443 long x;
444 memcpy((char *)&x, p, sizeof x);
445 return PyLong_FromLong(x);
446 }
447
448 static PyObject *
nu_ulong(const char * p,const formatdef * f)449 nu_ulong(const char *p, const formatdef *f)
450 {
451 unsigned long x;
452 memcpy((char *)&x, p, sizeof x);
453 return PyLong_FromUnsignedLong(x);
454 }
455
456 static PyObject *
nu_ssize_t(const char * p,const formatdef * f)457 nu_ssize_t(const char *p, const formatdef *f)
458 {
459 Py_ssize_t x;
460 memcpy((char *)&x, p, sizeof x);
461 return PyLong_FromSsize_t(x);
462 }
463
464 static PyObject *
nu_size_t(const char * p,const formatdef * f)465 nu_size_t(const char *p, const formatdef *f)
466 {
467 size_t x;
468 memcpy((char *)&x, p, sizeof x);
469 return PyLong_FromSize_t(x);
470 }
471
472 static PyObject *
nu_longlong(const char * p,const formatdef * f)473 nu_longlong(const char *p, const formatdef *f)
474 {
475 long long x;
476 memcpy((char *)&x, p, sizeof x);
477 return PyLong_FromLongLong(x);
478 }
479
480 static PyObject *
nu_ulonglong(const char * p,const formatdef * f)481 nu_ulonglong(const char *p, const formatdef *f)
482 {
483 unsigned long long x;
484 memcpy((char *)&x, p, sizeof x);
485 return PyLong_FromUnsignedLongLong(x);
486 }
487
488 static PyObject *
nu_bool(const char * p,const formatdef * f)489 nu_bool(const char *p, const formatdef *f)
490 {
491 _Bool x;
492 memcpy((char *)&x, p, sizeof x);
493 return PyBool_FromLong(x != 0);
494 }
495
496
497 static PyObject *
nu_halffloat(const char * p,const formatdef * f)498 nu_halffloat(const char *p, const formatdef *f)
499 {
500 #if PY_LITTLE_ENDIAN
501 return unpack_halffloat(p, 1);
502 #else
503 return unpack_halffloat(p, 0);
504 #endif
505 }
506
507 static PyObject *
nu_float(const char * p,const formatdef * f)508 nu_float(const char *p, const formatdef *f)
509 {
510 float x;
511 memcpy((char *)&x, p, sizeof x);
512 return PyFloat_FromDouble((double)x);
513 }
514
515 static PyObject *
nu_double(const char * p,const formatdef * f)516 nu_double(const char *p, const formatdef *f)
517 {
518 double x;
519 memcpy((char *)&x, p, sizeof x);
520 return PyFloat_FromDouble(x);
521 }
522
523 static PyObject *
nu_void_p(const char * p,const formatdef * f)524 nu_void_p(const char *p, const formatdef *f)
525 {
526 void *x;
527 memcpy((char *)&x, p, sizeof x);
528 return PyLong_FromVoidPtr(x);
529 }
530
531 static int
np_byte(char * p,PyObject * v,const formatdef * f)532 np_byte(char *p, PyObject *v, const formatdef *f)
533 {
534 long x;
535 if (get_long(v, &x) < 0)
536 return -1;
537 if (x < -128 || x > 127) {
538 PyErr_SetString(_structmodulestate_global->StructError,
539 "byte format requires -128 <= number <= 127");
540 return -1;
541 }
542 *p = (char)x;
543 return 0;
544 }
545
546 static int
np_ubyte(char * p,PyObject * v,const formatdef * f)547 np_ubyte(char *p, PyObject *v, const formatdef *f)
548 {
549 long x;
550 if (get_long(v, &x) < 0)
551 return -1;
552 if (x < 0 || x > 255) {
553 PyErr_SetString(_structmodulestate_global->StructError,
554 "ubyte format requires 0 <= number <= 255");
555 return -1;
556 }
557 *(unsigned char *)p = (unsigned char)x;
558 return 0;
559 }
560
561 static int
np_char(char * p,PyObject * v,const formatdef * f)562 np_char(char *p, PyObject *v, const formatdef *f)
563 {
564 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
565 PyErr_SetString(_structmodulestate_global->StructError,
566 "char format requires a bytes object of length 1");
567 return -1;
568 }
569 *p = *PyBytes_AS_STRING(v);
570 return 0;
571 }
572
573 static int
np_short(char * p,PyObject * v,const formatdef * f)574 np_short(char *p, PyObject *v, const formatdef *f)
575 {
576 long x;
577 short y;
578 if (get_long(v, &x) < 0)
579 return -1;
580 if (x < SHRT_MIN || x > SHRT_MAX) {
581 PyErr_SetString(_structmodulestate_global->StructError,
582 "short format requires " Py_STRINGIFY(SHRT_MIN)
583 " <= number <= " Py_STRINGIFY(SHRT_MAX));
584 return -1;
585 }
586 y = (short)x;
587 memcpy(p, (char *)&y, sizeof y);
588 return 0;
589 }
590
591 static int
np_ushort(char * p,PyObject * v,const formatdef * f)592 np_ushort(char *p, PyObject *v, const formatdef *f)
593 {
594 long x;
595 unsigned short y;
596 if (get_long(v, &x) < 0)
597 return -1;
598 if (x < 0 || x > USHRT_MAX) {
599 PyErr_SetString(_structmodulestate_global->StructError,
600 "ushort format requires 0 <= number <= "
601 Py_STRINGIFY(USHRT_MAX));
602 return -1;
603 }
604 y = (unsigned short)x;
605 memcpy(p, (char *)&y, sizeof y);
606 return 0;
607 }
608
609 static int
np_int(char * p,PyObject * v,const formatdef * f)610 np_int(char *p, PyObject *v, const formatdef *f)
611 {
612 long x;
613 int y;
614 if (get_long(v, &x) < 0)
615 return -1;
616 #if (SIZEOF_LONG > SIZEOF_INT)
617 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
618 RANGE_ERROR(x, f, 0, -1);
619 #endif
620 y = (int)x;
621 memcpy(p, (char *)&y, sizeof y);
622 return 0;
623 }
624
625 static int
np_uint(char * p,PyObject * v,const formatdef * f)626 np_uint(char *p, PyObject *v, const formatdef *f)
627 {
628 unsigned long x;
629 unsigned int y;
630 if (get_ulong(v, &x) < 0)
631 return -1;
632 y = (unsigned int)x;
633 #if (SIZEOF_LONG > SIZEOF_INT)
634 if (x > ((unsigned long)UINT_MAX))
635 RANGE_ERROR(y, f, 1, -1);
636 #endif
637 memcpy(p, (char *)&y, sizeof y);
638 return 0;
639 }
640
641 static int
np_long(char * p,PyObject * v,const formatdef * f)642 np_long(char *p, PyObject *v, const formatdef *f)
643 {
644 long x;
645 if (get_long(v, &x) < 0)
646 return -1;
647 memcpy(p, (char *)&x, sizeof x);
648 return 0;
649 }
650
651 static int
np_ulong(char * p,PyObject * v,const formatdef * f)652 np_ulong(char *p, PyObject *v, const formatdef *f)
653 {
654 unsigned long x;
655 if (get_ulong(v, &x) < 0)
656 return -1;
657 memcpy(p, (char *)&x, sizeof x);
658 return 0;
659 }
660
661 static int
np_ssize_t(char * p,PyObject * v,const formatdef * f)662 np_ssize_t(char *p, PyObject *v, const formatdef *f)
663 {
664 Py_ssize_t x;
665 if (get_ssize_t(v, &x) < 0)
666 return -1;
667 memcpy(p, (char *)&x, sizeof x);
668 return 0;
669 }
670
671 static int
np_size_t(char * p,PyObject * v,const formatdef * f)672 np_size_t(char *p, PyObject *v, const formatdef *f)
673 {
674 size_t x;
675 if (get_size_t(v, &x) < 0)
676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679 }
680
681 static int
np_longlong(char * p,PyObject * v,const formatdef * f)682 np_longlong(char *p, PyObject *v, const formatdef *f)
683 {
684 long long x;
685 if (get_longlong(v, &x) < 0)
686 return -1;
687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
689 }
690
691 static int
np_ulonglong(char * p,PyObject * v,const formatdef * f)692 np_ulonglong(char *p, PyObject *v, const formatdef *f)
693 {
694 unsigned long long x;
695 if (get_ulonglong(v, &x) < 0)
696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
699 }
700
701
702 static int
np_bool(char * p,PyObject * v,const formatdef * f)703 np_bool(char *p, PyObject *v, const formatdef *f)
704 {
705 int y;
706 _Bool x;
707 y = PyObject_IsTrue(v);
708 if (y < 0)
709 return -1;
710 x = y;
711 memcpy(p, (char *)&x, sizeof x);
712 return 0;
713 }
714
715 static int
np_halffloat(char * p,PyObject * v,const formatdef * f)716 np_halffloat(char *p, PyObject *v, const formatdef *f)
717 {
718 #if PY_LITTLE_ENDIAN
719 return pack_halffloat(p, v, 1);
720 #else
721 return pack_halffloat(p, v, 0);
722 #endif
723 }
724
725 static int
np_float(char * p,PyObject * v,const formatdef * f)726 np_float(char *p, PyObject *v, const formatdef *f)
727 {
728 float x = (float)PyFloat_AsDouble(v);
729 if (x == -1 && PyErr_Occurred()) {
730 PyErr_SetString(_structmodulestate_global->StructError,
731 "required argument is not a float");
732 return -1;
733 }
734 memcpy(p, (char *)&x, sizeof x);
735 return 0;
736 }
737
738 static int
np_double(char * p,PyObject * v,const formatdef * f)739 np_double(char *p, PyObject *v, const formatdef *f)
740 {
741 double x = PyFloat_AsDouble(v);
742 if (x == -1 && PyErr_Occurred()) {
743 PyErr_SetString(_structmodulestate_global->StructError,
744 "required argument is not a float");
745 return -1;
746 }
747 memcpy(p, (char *)&x, sizeof(double));
748 return 0;
749 }
750
751 static int
np_void_p(char * p,PyObject * v,const formatdef * f)752 np_void_p(char *p, PyObject *v, const formatdef *f)
753 {
754 void *x;
755
756 v = get_pylong(v);
757 if (v == NULL)
758 return -1;
759 assert(PyLong_Check(v));
760 x = PyLong_AsVoidPtr(v);
761 Py_DECREF(v);
762 if (x == NULL && PyErr_Occurred())
763 return -1;
764 memcpy(p, (char *)&x, sizeof x);
765 return 0;
766 }
767
768 static const formatdef native_table[] = {
769 {'x', sizeof(char), 0, NULL},
770 {'b', sizeof(char), 0, nu_byte, np_byte},
771 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
772 {'c', sizeof(char), 0, nu_char, np_char},
773 {'s', sizeof(char), 0, NULL},
774 {'p', sizeof(char), 0, NULL},
775 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
776 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
777 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
778 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
779 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
780 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
781 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
782 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
783 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
784 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
785 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
786 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
787 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
788 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
789 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
790 {0}
791 };
792
793 /* Big-endian routines. *****************************************************/
794
795 static PyObject *
bu_int(const char * p,const formatdef * f)796 bu_int(const char *p, const formatdef *f)
797 {
798 long x = 0;
799 Py_ssize_t i = f->size;
800 const unsigned char *bytes = (const unsigned char *)p;
801 do {
802 x = (x<<8) | *bytes++;
803 } while (--i > 0);
804 /* Extend the sign bit. */
805 if (SIZEOF_LONG > f->size)
806 x |= -(x & (1L << ((8 * f->size) - 1)));
807 return PyLong_FromLong(x);
808 }
809
810 static PyObject *
bu_uint(const char * p,const formatdef * f)811 bu_uint(const char *p, const formatdef *f)
812 {
813 unsigned long x = 0;
814 Py_ssize_t i = f->size;
815 const unsigned char *bytes = (const unsigned char *)p;
816 do {
817 x = (x<<8) | *bytes++;
818 } while (--i > 0);
819 return PyLong_FromUnsignedLong(x);
820 }
821
822 static PyObject *
bu_longlong(const char * p,const formatdef * f)823 bu_longlong(const char *p, const formatdef *f)
824 {
825 long long x = 0;
826 Py_ssize_t i = f->size;
827 const unsigned char *bytes = (const unsigned char *)p;
828 do {
829 x = (x<<8) | *bytes++;
830 } while (--i > 0);
831 /* Extend the sign bit. */
832 if (SIZEOF_LONG_LONG > f->size)
833 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
834 return PyLong_FromLongLong(x);
835 }
836
837 static PyObject *
bu_ulonglong(const char * p,const formatdef * f)838 bu_ulonglong(const char *p, const formatdef *f)
839 {
840 unsigned long long x = 0;
841 Py_ssize_t i = f->size;
842 const unsigned char *bytes = (const unsigned char *)p;
843 do {
844 x = (x<<8) | *bytes++;
845 } while (--i > 0);
846 return PyLong_FromUnsignedLongLong(x);
847 }
848
849 static PyObject *
bu_halffloat(const char * p,const formatdef * f)850 bu_halffloat(const char *p, const formatdef *f)
851 {
852 return unpack_halffloat(p, 0);
853 }
854
855 static PyObject *
bu_float(const char * p,const formatdef * f)856 bu_float(const char *p, const formatdef *f)
857 {
858 return unpack_float(p, 0);
859 }
860
861 static PyObject *
bu_double(const char * p,const formatdef * f)862 bu_double(const char *p, const formatdef *f)
863 {
864 return unpack_double(p, 0);
865 }
866
867 static PyObject *
bu_bool(const char * p,const formatdef * f)868 bu_bool(const char *p, const formatdef *f)
869 {
870 return PyBool_FromLong(*p != 0);
871 }
872
873 static int
bp_int(char * p,PyObject * v,const formatdef * f)874 bp_int(char *p, PyObject *v, const formatdef *f)
875 {
876 long x;
877 Py_ssize_t i;
878 unsigned char *q = (unsigned char *)p;
879 if (get_long(v, &x) < 0)
880 return -1;
881 i = f->size;
882 if (i != SIZEOF_LONG) {
883 if ((i == 2) && (x < -32768 || x > 32767))
884 RANGE_ERROR(x, f, 0, 0xffffL);
885 #if (SIZEOF_LONG != 4)
886 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
887 RANGE_ERROR(x, f, 0, 0xffffffffL);
888 #endif
889 }
890 do {
891 q[--i] = (unsigned char)(x & 0xffL);
892 x >>= 8;
893 } while (i > 0);
894 return 0;
895 }
896
897 static int
bp_uint(char * p,PyObject * v,const formatdef * f)898 bp_uint(char *p, PyObject *v, const formatdef *f)
899 {
900 unsigned long x;
901 Py_ssize_t i;
902 unsigned char *q = (unsigned char *)p;
903 if (get_ulong(v, &x) < 0)
904 return -1;
905 i = f->size;
906 if (i != SIZEOF_LONG) {
907 unsigned long maxint = 1;
908 maxint <<= (unsigned long)(i * 8);
909 if (x >= maxint)
910 RANGE_ERROR(x, f, 1, maxint - 1);
911 }
912 do {
913 q[--i] = (unsigned char)(x & 0xffUL);
914 x >>= 8;
915 } while (i > 0);
916 return 0;
917 }
918
919 static int
bp_longlong(char * p,PyObject * v,const formatdef * f)920 bp_longlong(char *p, PyObject *v, const formatdef *f)
921 {
922 int res;
923 v = get_pylong(v);
924 if (v == NULL)
925 return -1;
926 res = _PyLong_AsByteArray((PyLongObject *)v,
927 (unsigned char *)p,
928 8,
929 0, /* little_endian */
930 1 /* signed */);
931 Py_DECREF(v);
932 return res;
933 }
934
935 static int
bp_ulonglong(char * p,PyObject * v,const formatdef * f)936 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
937 {
938 int res;
939 v = get_pylong(v);
940 if (v == NULL)
941 return -1;
942 res = _PyLong_AsByteArray((PyLongObject *)v,
943 (unsigned char *)p,
944 8,
945 0, /* little_endian */
946 0 /* signed */);
947 Py_DECREF(v);
948 return res;
949 }
950
951 static int
bp_halffloat(char * p,PyObject * v,const formatdef * f)952 bp_halffloat(char *p, PyObject *v, const formatdef *f)
953 {
954 return pack_halffloat(p, v, 0);
955 }
956
957 static int
bp_float(char * p,PyObject * v,const formatdef * f)958 bp_float(char *p, PyObject *v, const formatdef *f)
959 {
960 double x = PyFloat_AsDouble(v);
961 if (x == -1 && PyErr_Occurred()) {
962 PyErr_SetString(_structmodulestate_global->StructError,
963 "required argument is not a float");
964 return -1;
965 }
966 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
967 }
968
969 static int
bp_double(char * p,PyObject * v,const formatdef * f)970 bp_double(char *p, PyObject *v, const formatdef *f)
971 {
972 double x = PyFloat_AsDouble(v);
973 if (x == -1 && PyErr_Occurred()) {
974 PyErr_SetString(_structmodulestate_global->StructError,
975 "required argument is not a float");
976 return -1;
977 }
978 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
979 }
980
981 static int
bp_bool(char * p,PyObject * v,const formatdef * f)982 bp_bool(char *p, PyObject *v, const formatdef *f)
983 {
984 int y;
985 y = PyObject_IsTrue(v);
986 if (y < 0)
987 return -1;
988 *p = (char)y;
989 return 0;
990 }
991
992 static formatdef bigendian_table[] = {
993 {'x', 1, 0, NULL},
994 {'b', 1, 0, nu_byte, np_byte},
995 {'B', 1, 0, nu_ubyte, np_ubyte},
996 {'c', 1, 0, nu_char, np_char},
997 {'s', 1, 0, NULL},
998 {'p', 1, 0, NULL},
999 {'h', 2, 0, bu_int, bp_int},
1000 {'H', 2, 0, bu_uint, bp_uint},
1001 {'i', 4, 0, bu_int, bp_int},
1002 {'I', 4, 0, bu_uint, bp_uint},
1003 {'l', 4, 0, bu_int, bp_int},
1004 {'L', 4, 0, bu_uint, bp_uint},
1005 {'q', 8, 0, bu_longlong, bp_longlong},
1006 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1007 {'?', 1, 0, bu_bool, bp_bool},
1008 {'e', 2, 0, bu_halffloat, bp_halffloat},
1009 {'f', 4, 0, bu_float, bp_float},
1010 {'d', 8, 0, bu_double, bp_double},
1011 {0}
1012 };
1013
1014 /* Little-endian routines. *****************************************************/
1015
1016 static PyObject *
lu_int(const char * p,const formatdef * f)1017 lu_int(const char *p, const formatdef *f)
1018 {
1019 long x = 0;
1020 Py_ssize_t i = f->size;
1021 const unsigned char *bytes = (const unsigned char *)p;
1022 do {
1023 x = (x<<8) | bytes[--i];
1024 } while (i > 0);
1025 /* Extend the sign bit. */
1026 if (SIZEOF_LONG > f->size)
1027 x |= -(x & (1L << ((8 * f->size) - 1)));
1028 return PyLong_FromLong(x);
1029 }
1030
1031 static PyObject *
lu_uint(const char * p,const formatdef * f)1032 lu_uint(const char *p, const formatdef *f)
1033 {
1034 unsigned long x = 0;
1035 Py_ssize_t i = f->size;
1036 const unsigned char *bytes = (const unsigned char *)p;
1037 do {
1038 x = (x<<8) | bytes[--i];
1039 } while (i > 0);
1040 return PyLong_FromUnsignedLong(x);
1041 }
1042
1043 static PyObject *
lu_longlong(const char * p,const formatdef * f)1044 lu_longlong(const char *p, const formatdef *f)
1045 {
1046 long long x = 0;
1047 Py_ssize_t i = f->size;
1048 const unsigned char *bytes = (const unsigned char *)p;
1049 do {
1050 x = (x<<8) | bytes[--i];
1051 } while (i > 0);
1052 /* Extend the sign bit. */
1053 if (SIZEOF_LONG_LONG > f->size)
1054 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
1055 return PyLong_FromLongLong(x);
1056 }
1057
1058 static PyObject *
lu_ulonglong(const char * p,const formatdef * f)1059 lu_ulonglong(const char *p, const formatdef *f)
1060 {
1061 unsigned long long x = 0;
1062 Py_ssize_t i = f->size;
1063 const unsigned char *bytes = (const unsigned char *)p;
1064 do {
1065 x = (x<<8) | bytes[--i];
1066 } while (i > 0);
1067 return PyLong_FromUnsignedLongLong(x);
1068 }
1069
1070 static PyObject *
lu_halffloat(const char * p,const formatdef * f)1071 lu_halffloat(const char *p, const formatdef *f)
1072 {
1073 return unpack_halffloat(p, 1);
1074 }
1075
1076 static PyObject *
lu_float(const char * p,const formatdef * f)1077 lu_float(const char *p, const formatdef *f)
1078 {
1079 return unpack_float(p, 1);
1080 }
1081
1082 static PyObject *
lu_double(const char * p,const formatdef * f)1083 lu_double(const char *p, const formatdef *f)
1084 {
1085 return unpack_double(p, 1);
1086 }
1087
1088 static int
lp_int(char * p,PyObject * v,const formatdef * f)1089 lp_int(char *p, PyObject *v, const formatdef *f)
1090 {
1091 long x;
1092 Py_ssize_t i;
1093 unsigned char *q = (unsigned char *)p;
1094 if (get_long(v, &x) < 0)
1095 return -1;
1096 i = f->size;
1097 if (i != SIZEOF_LONG) {
1098 if ((i == 2) && (x < -32768 || x > 32767))
1099 RANGE_ERROR(x, f, 0, 0xffffL);
1100 #if (SIZEOF_LONG != 4)
1101 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1102 RANGE_ERROR(x, f, 0, 0xffffffffL);
1103 #endif
1104 }
1105 do {
1106 *q++ = (unsigned char)(x & 0xffL);
1107 x >>= 8;
1108 } while (--i > 0);
1109 return 0;
1110 }
1111
1112 static int
lp_uint(char * p,PyObject * v,const formatdef * f)1113 lp_uint(char *p, PyObject *v, const formatdef *f)
1114 {
1115 unsigned long x;
1116 Py_ssize_t i;
1117 unsigned char *q = (unsigned char *)p;
1118 if (get_ulong(v, &x) < 0)
1119 return -1;
1120 i = f->size;
1121 if (i != SIZEOF_LONG) {
1122 unsigned long maxint = 1;
1123 maxint <<= (unsigned long)(i * 8);
1124 if (x >= maxint)
1125 RANGE_ERROR(x, f, 1, maxint - 1);
1126 }
1127 do {
1128 *q++ = (unsigned char)(x & 0xffUL);
1129 x >>= 8;
1130 } while (--i > 0);
1131 return 0;
1132 }
1133
1134 static int
lp_longlong(char * p,PyObject * v,const formatdef * f)1135 lp_longlong(char *p, PyObject *v, const formatdef *f)
1136 {
1137 int res;
1138 v = get_pylong(v);
1139 if (v == NULL)
1140 return -1;
1141 res = _PyLong_AsByteArray((PyLongObject*)v,
1142 (unsigned char *)p,
1143 8,
1144 1, /* little_endian */
1145 1 /* signed */);
1146 Py_DECREF(v);
1147 return res;
1148 }
1149
1150 static int
lp_ulonglong(char * p,PyObject * v,const formatdef * f)1151 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1152 {
1153 int res;
1154 v = get_pylong(v);
1155 if (v == NULL)
1156 return -1;
1157 res = _PyLong_AsByteArray((PyLongObject*)v,
1158 (unsigned char *)p,
1159 8,
1160 1, /* little_endian */
1161 0 /* signed */);
1162 Py_DECREF(v);
1163 return res;
1164 }
1165
1166 static int
lp_halffloat(char * p,PyObject * v,const formatdef * f)1167 lp_halffloat(char *p, PyObject *v, const formatdef *f)
1168 {
1169 return pack_halffloat(p, v, 1);
1170 }
1171
1172 static int
lp_float(char * p,PyObject * v,const formatdef * f)1173 lp_float(char *p, PyObject *v, const formatdef *f)
1174 {
1175 double x = PyFloat_AsDouble(v);
1176 if (x == -1 && PyErr_Occurred()) {
1177 PyErr_SetString(_structmodulestate_global->StructError,
1178 "required argument is not a float");
1179 return -1;
1180 }
1181 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1182 }
1183
1184 static int
lp_double(char * p,PyObject * v,const formatdef * f)1185 lp_double(char *p, PyObject *v, const formatdef *f)
1186 {
1187 double x = PyFloat_AsDouble(v);
1188 if (x == -1 && PyErr_Occurred()) {
1189 PyErr_SetString(_structmodulestate_global->StructError,
1190 "required argument is not a float");
1191 return -1;
1192 }
1193 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1194 }
1195
1196 static formatdef lilendian_table[] = {
1197 {'x', 1, 0, NULL},
1198 {'b', 1, 0, nu_byte, np_byte},
1199 {'B', 1, 0, nu_ubyte, np_ubyte},
1200 {'c', 1, 0, nu_char, np_char},
1201 {'s', 1, 0, NULL},
1202 {'p', 1, 0, NULL},
1203 {'h', 2, 0, lu_int, lp_int},
1204 {'H', 2, 0, lu_uint, lp_uint},
1205 {'i', 4, 0, lu_int, lp_int},
1206 {'I', 4, 0, lu_uint, lp_uint},
1207 {'l', 4, 0, lu_int, lp_int},
1208 {'L', 4, 0, lu_uint, lp_uint},
1209 {'q', 8, 0, lu_longlong, lp_longlong},
1210 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1211 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1212 but potentially different from native rep -- reuse bx_bool funcs. */
1213 {'e', 2, 0, lu_halffloat, lp_halffloat},
1214 {'f', 4, 0, lu_float, lp_float},
1215 {'d', 8, 0, lu_double, lp_double},
1216 {0}
1217 };
1218
1219
1220 static const formatdef *
whichtable(const char ** pfmt)1221 whichtable(const char **pfmt)
1222 {
1223 const char *fmt = (*pfmt)++; /* May be backed out of later */
1224 switch (*fmt) {
1225 case '<':
1226 return lilendian_table;
1227 case '>':
1228 case '!': /* Network byte order is big-endian */
1229 return bigendian_table;
1230 case '=': { /* Host byte order -- different from native in alignment! */
1231 #if PY_LITTLE_ENDIAN
1232 return lilendian_table;
1233 #else
1234 return bigendian_table;
1235 #endif
1236 }
1237 default:
1238 --*pfmt; /* Back out of pointer increment */
1239 /* Fall through */
1240 case '@':
1241 return native_table;
1242 }
1243 }
1244
1245
1246 /* Get the table entry for a format code */
1247
1248 static const formatdef *
getentry(int c,const formatdef * f)1249 getentry(int c, const formatdef *f)
1250 {
1251 for (; f->format != '\0'; f++) {
1252 if (f->format == c) {
1253 return f;
1254 }
1255 }
1256 PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format");
1257 return NULL;
1258 }
1259
1260
1261 /* Align a size according to a format code. Return -1 on overflow. */
1262
1263 static Py_ssize_t
align(Py_ssize_t size,char c,const formatdef * e)1264 align(Py_ssize_t size, char c, const formatdef *e)
1265 {
1266 Py_ssize_t extra;
1267
1268 if (e->format == c) {
1269 if (e->alignment && size > 0) {
1270 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1271 if (extra > PY_SSIZE_T_MAX - size)
1272 return -1;
1273 size += extra;
1274 }
1275 }
1276 return size;
1277 }
1278
1279 /*
1280 * Struct object implementation.
1281 */
1282
1283 /* calculate the size of a format string */
1284
1285 static int
prepare_s(PyStructObject * self)1286 prepare_s(PyStructObject *self)
1287 {
1288 const formatdef *f;
1289 const formatdef *e;
1290 formatcode *codes;
1291
1292 const char *s;
1293 const char *fmt;
1294 char c;
1295 Py_ssize_t size, len, num, itemsize;
1296 size_t ncodes;
1297
1298 fmt = PyBytes_AS_STRING(self->s_format);
1299 if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
1300 PyErr_SetString(_structmodulestate_global->StructError,
1301 "embedded null character");
1302 return -1;
1303 }
1304
1305 f = whichtable(&fmt);
1306
1307 s = fmt;
1308 size = 0;
1309 len = 0;
1310 ncodes = 0;
1311 while ((c = *s++) != '\0') {
1312 if (Py_ISSPACE(c))
1313 continue;
1314 if ('0' <= c && c <= '9') {
1315 num = c - '0';
1316 while ('0' <= (c = *s++) && c <= '9') {
1317 /* overflow-safe version of
1318 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1319 if (num >= PY_SSIZE_T_MAX / 10 && (
1320 num > PY_SSIZE_T_MAX / 10 ||
1321 (c - '0') > PY_SSIZE_T_MAX % 10))
1322 goto overflow;
1323 num = num*10 + (c - '0');
1324 }
1325 if (c == '\0') {
1326 PyErr_SetString(_structmodulestate_global->StructError,
1327 "repeat count given without format specifier");
1328 return -1;
1329 }
1330 }
1331 else
1332 num = 1;
1333
1334 e = getentry(c, f);
1335 if (e == NULL)
1336 return -1;
1337
1338 switch (c) {
1339 case 's': /* fall through */
1340 case 'p': len++; ncodes++; break;
1341 case 'x': break;
1342 default: len += num; if (num) ncodes++; break;
1343 }
1344
1345 itemsize = e->size;
1346 size = align(size, c, e);
1347 if (size == -1)
1348 goto overflow;
1349
1350 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1351 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1352 goto overflow;
1353 size += num * itemsize;
1354 }
1355
1356 /* check for overflow */
1357 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
1358 PyErr_NoMemory();
1359 return -1;
1360 }
1361
1362 self->s_size = size;
1363 self->s_len = len;
1364 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
1365 if (codes == NULL) {
1366 PyErr_NoMemory();
1367 return -1;
1368 }
1369 /* Free any s_codes value left over from a previous initialization. */
1370 if (self->s_codes != NULL)
1371 PyMem_FREE(self->s_codes);
1372 self->s_codes = codes;
1373
1374 s = fmt;
1375 size = 0;
1376 while ((c = *s++) != '\0') {
1377 if (Py_ISSPACE(c))
1378 continue;
1379 if ('0' <= c && c <= '9') {
1380 num = c - '0';
1381 while ('0' <= (c = *s++) && c <= '9')
1382 num = num*10 + (c - '0');
1383 }
1384 else
1385 num = 1;
1386
1387 e = getentry(c, f);
1388
1389 size = align(size, c, e);
1390 if (c == 's' || c == 'p') {
1391 codes->offset = size;
1392 codes->size = num;
1393 codes->fmtdef = e;
1394 codes->repeat = 1;
1395 codes++;
1396 size += num;
1397 } else if (c == 'x') {
1398 size += num;
1399 } else if (num) {
1400 codes->offset = size;
1401 codes->size = e->size;
1402 codes->fmtdef = e;
1403 codes->repeat = num;
1404 codes++;
1405 size += e->size * num;
1406 }
1407 }
1408 codes->fmtdef = NULL;
1409 codes->offset = size;
1410 codes->size = 0;
1411 codes->repeat = 0;
1412
1413 return 0;
1414
1415 overflow:
1416 PyErr_SetString(_structmodulestate_global->StructError,
1417 "total struct size too long");
1418 return -1;
1419 }
1420
1421 static PyObject *
s_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1422 s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1423 {
1424 PyObject *self;
1425
1426 assert(type != NULL);
1427 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1428 assert(alloc_func != NULL);
1429
1430 self = alloc_func(type, 0);
1431 if (self != NULL) {
1432 PyStructObject *s = (PyStructObject*)self;
1433 Py_INCREF(Py_None);
1434 s->s_format = Py_None;
1435 s->s_codes = NULL;
1436 s->s_size = -1;
1437 s->s_len = -1;
1438 }
1439 return self;
1440 }
1441
1442 /*[clinic input]
1443 Struct.__init__
1444
1445 format: object
1446
1447 Create a compiled struct object.
1448
1449 Return a new Struct object which writes and reads binary data according to
1450 the format string.
1451
1452 See help(struct) for more on format strings.
1453 [clinic start generated code]*/
1454
1455 static int
Struct___init___impl(PyStructObject * self,PyObject * format)1456 Struct___init___impl(PyStructObject *self, PyObject *format)
1457 /*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
1458 {
1459 int ret = 0;
1460
1461 if (PyUnicode_Check(format)) {
1462 format = PyUnicode_AsASCIIString(format);
1463 if (format == NULL)
1464 return -1;
1465 }
1466 /* XXX support buffer interface, too */
1467 else {
1468 Py_INCREF(format);
1469 }
1470
1471 if (!PyBytes_Check(format)) {
1472 Py_DECREF(format);
1473 PyErr_Format(PyExc_TypeError,
1474 "Struct() argument 1 must be a str or bytes object, "
1475 "not %.200s",
1476 _PyType_Name(Py_TYPE(format)));
1477 return -1;
1478 }
1479
1480 Py_SETREF(self->s_format, format);
1481
1482 ret = prepare_s(self);
1483 return ret;
1484 }
1485
1486 static void
s_dealloc(PyStructObject * s)1487 s_dealloc(PyStructObject *s)
1488 {
1489 PyTypeObject *tp = Py_TYPE(s);
1490 if (s->weakreflist != NULL)
1491 PyObject_ClearWeakRefs((PyObject *)s);
1492 if (s->s_codes != NULL) {
1493 PyMem_FREE(s->s_codes);
1494 }
1495 Py_XDECREF(s->s_format);
1496 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1497 free_func(s);
1498 Py_DECREF(tp);
1499 }
1500
1501 static PyObject *
s_unpack_internal(PyStructObject * soself,const char * startfrom)1502 s_unpack_internal(PyStructObject *soself, const char *startfrom) {
1503 formatcode *code;
1504 Py_ssize_t i = 0;
1505 PyObject *result = PyTuple_New(soself->s_len);
1506 if (result == NULL)
1507 return NULL;
1508
1509 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1510 const formatdef *e = code->fmtdef;
1511 const char *res = startfrom + code->offset;
1512 Py_ssize_t j = code->repeat;
1513 while (j--) {
1514 PyObject *v;
1515 if (e->format == 's') {
1516 v = PyBytes_FromStringAndSize(res, code->size);
1517 } else if (e->format == 'p') {
1518 Py_ssize_t n = *(unsigned char*)res;
1519 if (n >= code->size)
1520 n = code->size - 1;
1521 v = PyBytes_FromStringAndSize(res + 1, n);
1522 } else {
1523 v = e->unpack(res, e);
1524 }
1525 if (v == NULL)
1526 goto fail;
1527 PyTuple_SET_ITEM(result, i++, v);
1528 res += code->size;
1529 }
1530 }
1531
1532 return result;
1533 fail:
1534 Py_DECREF(result);
1535 return NULL;
1536 }
1537
1538
1539 /*[clinic input]
1540 Struct.unpack
1541
1542 buffer: Py_buffer
1543 /
1544
1545 Return a tuple containing unpacked values.
1546
1547 Unpack according to the format string Struct.format. The buffer's size
1548 in bytes must be Struct.size.
1549
1550 See help(struct) for more on format strings.
1551 [clinic start generated code]*/
1552
1553 static PyObject *
Struct_unpack_impl(PyStructObject * self,Py_buffer * buffer)1554 Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1555 /*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
1556 {
1557 assert(self->s_codes != NULL);
1558 if (buffer->len != self->s_size) {
1559 PyErr_Format(_structmodulestate_global->StructError,
1560 "unpack requires a buffer of %zd bytes",
1561 self->s_size);
1562 return NULL;
1563 }
1564 return s_unpack_internal(self, buffer->buf);
1565 }
1566
1567 /*[clinic input]
1568 Struct.unpack_from
1569
1570 buffer: Py_buffer
1571 offset: Py_ssize_t = 0
1572
1573 Return a tuple containing unpacked values.
1574
1575 Values are unpacked according to the format string Struct.format.
1576
1577 The buffer's size in bytes, starting at position offset, must be
1578 at least Struct.size.
1579
1580 See help(struct) for more on format strings.
1581 [clinic start generated code]*/
1582
1583 static PyObject *
Struct_unpack_from_impl(PyStructObject * self,Py_buffer * buffer,Py_ssize_t offset)1584 Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1585 Py_ssize_t offset)
1586 /*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
1587 {
1588 assert(self->s_codes != NULL);
1589
1590 if (offset < 0) {
1591 if (offset + self->s_size > 0) {
1592 PyErr_Format(_structmodulestate_global->StructError,
1593 "not enough data to unpack %zd bytes at offset %zd",
1594 self->s_size,
1595 offset);
1596 return NULL;
1597 }
1598
1599 if (offset + buffer->len < 0) {
1600 PyErr_Format(_structmodulestate_global->StructError,
1601 "offset %zd out of range for %zd-byte buffer",
1602 offset,
1603 buffer->len);
1604 return NULL;
1605 }
1606 offset += buffer->len;
1607 }
1608
1609 if ((buffer->len - offset) < self->s_size) {
1610 PyErr_Format(_structmodulestate_global->StructError,
1611 "unpack_from requires a buffer of at least %zu bytes for "
1612 "unpacking %zd bytes at offset %zd "
1613 "(actual buffer size is %zd)",
1614 (size_t)self->s_size + (size_t)offset,
1615 self->s_size,
1616 offset,
1617 buffer->len);
1618 return NULL;
1619 }
1620 return s_unpack_internal(self, (char*)buffer->buf + offset);
1621 }
1622
1623
1624
1625 /* Unpack iterator type */
1626
1627 typedef struct {
1628 PyObject_HEAD
1629 PyStructObject *so;
1630 Py_buffer buf;
1631 Py_ssize_t index;
1632 } unpackiterobject;
1633
1634 static void
unpackiter_dealloc(unpackiterobject * self)1635 unpackiter_dealloc(unpackiterobject *self)
1636 {
1637 /* bpo-31095: UnTrack is needed before calling any callbacks */
1638 PyTypeObject *tp = Py_TYPE(self);
1639 PyObject_GC_UnTrack(self);
1640 Py_XDECREF(self->so);
1641 PyBuffer_Release(&self->buf);
1642 PyObject_GC_Del(self);
1643 Py_DECREF(tp);
1644 }
1645
1646 static int
unpackiter_traverse(unpackiterobject * self,visitproc visit,void * arg)1647 unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1648 {
1649 Py_VISIT(Py_TYPE(self));
1650 Py_VISIT(self->so);
1651 Py_VISIT(self->buf.obj);
1652 return 0;
1653 }
1654
1655 static PyObject *
unpackiter_len(unpackiterobject * self,PyObject * Py_UNUSED (ignored))1656 unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
1657 {
1658 Py_ssize_t len;
1659 if (self->so == NULL)
1660 len = 0;
1661 else
1662 len = (self->buf.len - self->index) / self->so->s_size;
1663 return PyLong_FromSsize_t(len);
1664 }
1665
1666 static PyMethodDef unpackiter_methods[] = {
1667 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1668 {NULL, NULL} /* sentinel */
1669 };
1670
1671 static PyObject *
unpackiter_iternext(unpackiterobject * self)1672 unpackiter_iternext(unpackiterobject *self)
1673 {
1674 PyObject *result;
1675 if (self->so == NULL)
1676 return NULL;
1677 if (self->index >= self->buf.len) {
1678 /* Iterator exhausted */
1679 Py_CLEAR(self->so);
1680 PyBuffer_Release(&self->buf);
1681 return NULL;
1682 }
1683 assert(self->index + self->so->s_size <= self->buf.len);
1684 result = s_unpack_internal(self->so,
1685 (char*) self->buf.buf + self->index);
1686 self->index += self->so->s_size;
1687 return result;
1688 }
1689
unpackiter_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1690 PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1691 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1692 return NULL;
1693 }
1694
1695 static PyType_Slot unpackiter_type_slots[] = {
1696 {Py_tp_dealloc, unpackiter_dealloc},
1697 {Py_tp_getattro, PyObject_GenericGetAttr},
1698 {Py_tp_traverse, unpackiter_traverse},
1699 {Py_tp_iter, PyObject_SelfIter},
1700 {Py_tp_iternext, unpackiter_iternext},
1701 {Py_tp_methods, unpackiter_methods},
1702 {Py_tp_new, unpackiter_new},
1703 {0, 0},
1704 };
1705
1706 static PyType_Spec unpackiter_type_spec = {
1707 "_struct.unpack_iterator",
1708 sizeof(unpackiterobject),
1709 0,
1710 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1711 unpackiter_type_slots
1712 };
1713
1714 /*[clinic input]
1715 Struct.iter_unpack
1716
1717 buffer: object
1718 /
1719
1720 Return an iterator yielding tuples.
1721
1722 Tuples are unpacked from the given bytes source, like a repeated
1723 invocation of unpack_from().
1724
1725 Requires that the bytes length be a multiple of the struct size.
1726 [clinic start generated code]*/
1727
1728 static PyObject *
Struct_iter_unpack(PyStructObject * self,PyObject * buffer)1729 Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1730 /*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
1731 {
1732 unpackiterobject *iter;
1733
1734 assert(self->s_codes != NULL);
1735
1736 if (self->s_size == 0) {
1737 PyErr_Format(_structmodulestate_global->StructError,
1738 "cannot iteratively unpack with a struct of length 0");
1739 return NULL;
1740 }
1741
1742 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0);
1743 if (iter == NULL)
1744 return NULL;
1745
1746 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1747 Py_DECREF(iter);
1748 return NULL;
1749 }
1750 if (iter->buf.len % self->s_size != 0) {
1751 PyErr_Format(_structmodulestate_global->StructError,
1752 "iterative unpacking requires a buffer of "
1753 "a multiple of %zd bytes",
1754 self->s_size);
1755 Py_DECREF(iter);
1756 return NULL;
1757 }
1758 Py_INCREF(self);
1759 iter->so = self;
1760 iter->index = 0;
1761 return (PyObject *)iter;
1762 }
1763
1764
1765 /*
1766 * Guts of the pack function.
1767 *
1768 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1769 * argument for where to start processing the arguments for packing, and a
1770 * character buffer for writing the packed string. The caller must insure
1771 * that the buffer may contain the required length for packing the arguments.
1772 * 0 is returned on success, 1 is returned if there is an error.
1773 *
1774 */
1775 static int
s_pack_internal(PyStructObject * soself,PyObject * const * args,int offset,char * buf)1776 s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
1777 {
1778 formatcode *code;
1779 /* XXX(nnorwitz): why does i need to be a local? can we use
1780 the offset parameter or do we need the wider width? */
1781 Py_ssize_t i;
1782
1783 memset(buf, '\0', soself->s_size);
1784 i = offset;
1785 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1786 const formatdef *e = code->fmtdef;
1787 char *res = buf + code->offset;
1788 Py_ssize_t j = code->repeat;
1789 while (j--) {
1790 PyObject *v = args[i++];
1791 if (e->format == 's') {
1792 Py_ssize_t n;
1793 int isstring;
1794 const void *p;
1795 isstring = PyBytes_Check(v);
1796 if (!isstring && !PyByteArray_Check(v)) {
1797 PyErr_SetString(_structmodulestate_global->StructError,
1798 "argument for 's' must be a bytes object");
1799 return -1;
1800 }
1801 if (isstring) {
1802 n = PyBytes_GET_SIZE(v);
1803 p = PyBytes_AS_STRING(v);
1804 }
1805 else {
1806 n = PyByteArray_GET_SIZE(v);
1807 p = PyByteArray_AS_STRING(v);
1808 }
1809 if (n > code->size)
1810 n = code->size;
1811 if (n > 0)
1812 memcpy(res, p, n);
1813 } else if (e->format == 'p') {
1814 Py_ssize_t n;
1815 int isstring;
1816 const void *p;
1817 isstring = PyBytes_Check(v);
1818 if (!isstring && !PyByteArray_Check(v)) {
1819 PyErr_SetString(_structmodulestate_global->StructError,
1820 "argument for 'p' must be a bytes object");
1821 return -1;
1822 }
1823 if (isstring) {
1824 n = PyBytes_GET_SIZE(v);
1825 p = PyBytes_AS_STRING(v);
1826 }
1827 else {
1828 n = PyByteArray_GET_SIZE(v);
1829 p = PyByteArray_AS_STRING(v);
1830 }
1831 if (n > (code->size - 1))
1832 n = code->size - 1;
1833 if (n > 0)
1834 memcpy(res + 1, p, n);
1835 if (n > 255)
1836 n = 255;
1837 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1838 } else {
1839 if (e->pack(res, v, e) < 0) {
1840 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1841 PyErr_SetString(_structmodulestate_global->StructError,
1842 "int too large to convert");
1843 return -1;
1844 }
1845 }
1846 res += code->size;
1847 }
1848 }
1849
1850 /* Success */
1851 return 0;
1852 }
1853
1854
1855 PyDoc_STRVAR(s_pack__doc__,
1856 "S.pack(v1, v2, ...) -> bytes\n\
1857 \n\
1858 Return a bytes object containing values v1, v2, ... packed according\n\
1859 to the format string S.format. See help(struct) for more on format\n\
1860 strings.");
1861
1862 static PyObject *
s_pack(PyObject * self,PyObject * const * args,Py_ssize_t nargs)1863 s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1864 {
1865 char *buf;
1866 PyStructObject *soself;
1867
1868 /* Validate arguments. */
1869 soself = (PyStructObject *)self;
1870 assert(PyStruct_Check(self));
1871 assert(soself->s_codes != NULL);
1872 if (nargs != soself->s_len)
1873 {
1874 PyErr_Format(_structmodulestate_global->StructError,
1875 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1876 return NULL;
1877 }
1878
1879 /* Allocate a new string */
1880 _PyBytesWriter writer;
1881 _PyBytesWriter_Init(&writer);
1882 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1883 if (buf == NULL) {
1884 _PyBytesWriter_Dealloc(&writer);
1885 return NULL;
1886 }
1887
1888 /* Call the guts */
1889 if ( s_pack_internal(soself, args, 0, buf) != 0 ) {
1890 _PyBytesWriter_Dealloc(&writer);
1891 return NULL;
1892 }
1893
1894 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
1895 }
1896
1897 PyDoc_STRVAR(s_pack_into__doc__,
1898 "S.pack_into(buffer, offset, v1, v2, ...)\n\
1899 \n\
1900 Pack the values v1, v2, ... according to the format string S.format\n\
1901 and write the packed bytes into the writable buffer buf starting at\n\
1902 offset. Note that the offset is a required argument. See\n\
1903 help(struct) for more on format strings.");
1904
1905 static PyObject *
s_pack_into(PyObject * self,PyObject * const * args,Py_ssize_t nargs)1906 s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1907 {
1908 PyStructObject *soself;
1909 Py_buffer buffer;
1910 Py_ssize_t offset;
1911
1912 /* Validate arguments. +1 is for the first arg as buffer. */
1913 soself = (PyStructObject *)self;
1914 assert(PyStruct_Check(self));
1915 assert(soself->s_codes != NULL);
1916 if (nargs != (soself->s_len + 2))
1917 {
1918 if (nargs == 0) {
1919 PyErr_Format(_structmodulestate_global->StructError,
1920 "pack_into expected buffer argument");
1921 }
1922 else if (nargs == 1) {
1923 PyErr_Format(_structmodulestate_global->StructError,
1924 "pack_into expected offset argument");
1925 }
1926 else {
1927 PyErr_Format(_structmodulestate_global->StructError,
1928 "pack_into expected %zd items for packing (got %zd)",
1929 soself->s_len, (nargs - 2));
1930 }
1931 return NULL;
1932 }
1933
1934 /* Extract a writable memory buffer from the first argument */
1935 if (!PyArg_Parse(args[0], "w*", &buffer))
1936 return NULL;
1937 assert(buffer.len >= 0);
1938
1939 /* Extract the offset from the first argument */
1940 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
1941 if (offset == -1 && PyErr_Occurred()) {
1942 PyBuffer_Release(&buffer);
1943 return NULL;
1944 }
1945
1946 /* Support negative offsets. */
1947 if (offset < 0) {
1948 /* Check that negative offset is low enough to fit data */
1949 if (offset + soself->s_size > 0) {
1950 PyErr_Format(_structmodulestate_global->StructError,
1951 "no space to pack %zd bytes at offset %zd",
1952 soself->s_size,
1953 offset);
1954 PyBuffer_Release(&buffer);
1955 return NULL;
1956 }
1957
1958 /* Check that negative offset is not crossing buffer boundary */
1959 if (offset + buffer.len < 0) {
1960 PyErr_Format(_structmodulestate_global->StructError,
1961 "offset %zd out of range for %zd-byte buffer",
1962 offset,
1963 buffer.len);
1964 PyBuffer_Release(&buffer);
1965 return NULL;
1966 }
1967
1968 offset += buffer.len;
1969 }
1970
1971 /* Check boundaries */
1972 if ((buffer.len - offset) < soself->s_size) {
1973 assert(offset >= 0);
1974 assert(soself->s_size >= 0);
1975
1976 PyErr_Format(_structmodulestate_global->StructError,
1977 "pack_into requires a buffer of at least %zu bytes for "
1978 "packing %zd bytes at offset %zd "
1979 "(actual buffer size is %zd)",
1980 (size_t)soself->s_size + (size_t)offset,
1981 soself->s_size,
1982 offset,
1983 buffer.len);
1984 PyBuffer_Release(&buffer);
1985 return NULL;
1986 }
1987
1988 /* Call the guts */
1989 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1990 PyBuffer_Release(&buffer);
1991 return NULL;
1992 }
1993
1994 PyBuffer_Release(&buffer);
1995 Py_RETURN_NONE;
1996 }
1997
1998 static PyObject *
s_get_format(PyStructObject * self,void * unused)1999 s_get_format(PyStructObject *self, void *unused)
2000 {
2001 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
2002 PyBytes_GET_SIZE(self->s_format));
2003 }
2004
2005 static PyObject *
s_get_size(PyStructObject * self,void * unused)2006 s_get_size(PyStructObject *self, void *unused)
2007 {
2008 return PyLong_FromSsize_t(self->s_size);
2009 }
2010
2011 PyDoc_STRVAR(s_sizeof__doc__,
2012 "S.__sizeof__() -> size of S in memory, in bytes");
2013
2014 static PyObject *
s_sizeof(PyStructObject * self,void * unused)2015 s_sizeof(PyStructObject *self, void *unused)
2016 {
2017 Py_ssize_t size;
2018 formatcode *code;
2019
2020 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
2021 for (code = self->s_codes; code->fmtdef != NULL; code++)
2022 size += sizeof(formatcode);
2023 return PyLong_FromSsize_t(size);
2024 }
2025
2026 /* List of functions */
2027
2028 static struct PyMethodDef s_methods[] = {
2029 STRUCT_ITER_UNPACK_METHODDEF
2030 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2031 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
2032 STRUCT_UNPACK_METHODDEF
2033 STRUCT_UNPACK_FROM_METHODDEF
2034 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
2035 {NULL, NULL} /* sentinel */
2036 };
2037
2038 static PyMemberDef s_members[] = {
2039 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
2040 {NULL} /* sentinel */
2041 };
2042
2043 #define OFF(x) offsetof(PyStructObject, x)
2044
2045 static PyGetSetDef s_getsetlist[] = {
2046 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2047 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2048 {NULL} /* sentinel */
2049 };
2050
2051 PyDoc_STRVAR(s__doc__,
2052 "Struct(fmt) --> compiled struct object\n"
2053 "\n"
2054 );
2055
2056 static PyType_Slot PyStructType_slots[] = {
2057 {Py_tp_dealloc, s_dealloc},
2058 {Py_tp_getattro, PyObject_GenericGetAttr},
2059 {Py_tp_setattro, PyObject_GenericSetAttr},
2060 {Py_tp_doc, (void*)s__doc__},
2061 {Py_tp_methods, s_methods},
2062 {Py_tp_members, s_members},
2063 {Py_tp_getset, s_getsetlist},
2064 {Py_tp_init, Struct___init__},
2065 {Py_tp_alloc, PyType_GenericAlloc},
2066 {Py_tp_new, s_new},
2067 {Py_tp_free, PyObject_Del},
2068 {0, 0},
2069 };
2070
2071 static PyType_Spec PyStructType_spec = {
2072 "_struct.Struct",
2073 sizeof(PyStructObject),
2074 0,
2075 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2076 PyStructType_slots
2077 };
2078
2079
2080 /* ---- Standalone functions ---- */
2081
2082 #define MAXCACHE 100
2083 static PyObject *cache = NULL;
2084
2085 static int
cache_struct_converter(PyObject * fmt,PyStructObject ** ptr)2086 cache_struct_converter(PyObject *fmt, PyStructObject **ptr)
2087 {
2088 PyObject * s_object;
2089
2090 if (fmt == NULL) {
2091 Py_DECREF(*ptr);
2092 *ptr = NULL;
2093 return 1;
2094 }
2095
2096 if (cache == NULL) {
2097 cache = PyDict_New();
2098 if (cache == NULL)
2099 return 0;
2100 }
2101
2102 s_object = PyDict_GetItemWithError(cache, fmt);
2103 if (s_object != NULL) {
2104 Py_INCREF(s_object);
2105 *ptr = (PyStructObject *)s_object;
2106 return Py_CLEANUP_SUPPORTED;
2107 }
2108 else if (PyErr_Occurred()) {
2109 return 0;
2110 }
2111
2112 s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt);
2113 if (s_object != NULL) {
2114 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
2115 PyDict_Clear(cache);
2116 /* Attempt to cache the result */
2117 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2118 PyErr_Clear();
2119 *ptr = (PyStructObject *)s_object;
2120 return Py_CLEANUP_SUPPORTED;
2121 }
2122 return 0;
2123 }
2124
2125 /*[clinic input]
2126 _clearcache
2127
2128 Clear the internal cache.
2129 [clinic start generated code]*/
2130
2131 static PyObject *
_clearcache_impl(PyObject * module)2132 _clearcache_impl(PyObject *module)
2133 /*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
2134 {
2135 Py_CLEAR(cache);
2136 Py_RETURN_NONE;
2137 }
2138
2139
2140 /*[clinic input]
2141 calcsize -> Py_ssize_t
2142
2143 format as s_object: cache_struct
2144 /
2145
2146 Return size in bytes of the struct described by the format string.
2147 [clinic start generated code]*/
2148
2149 static Py_ssize_t
calcsize_impl(PyObject * module,PyStructObject * s_object)2150 calcsize_impl(PyObject *module, PyStructObject *s_object)
2151 /*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
2152 {
2153 return s_object->s_size;
2154 }
2155
2156 PyDoc_STRVAR(pack_doc,
2157 "pack(format, v1, v2, ...) -> bytes\n\
2158 \n\
2159 Return a bytes object containing the values v1, v2, ... packed according\n\
2160 to the format string. See help(struct) for more on format strings.");
2161
2162 static PyObject *
pack(PyObject * self,PyObject * const * args,Py_ssize_t nargs)2163 pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2164 {
2165 PyObject *s_object = NULL;
2166 PyObject *format, *result;
2167
2168 if (nargs == 0) {
2169 PyErr_SetString(PyExc_TypeError, "missing format argument");
2170 return NULL;
2171 }
2172 format = args[0];
2173
2174 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
2175 return NULL;
2176 }
2177 result = s_pack(s_object, args + 1, nargs - 1);
2178 Py_DECREF(s_object);
2179 return result;
2180 }
2181
2182 PyDoc_STRVAR(pack_into_doc,
2183 "pack_into(format, buffer, offset, v1, v2, ...)\n\
2184 \n\
2185 Pack the values v1, v2, ... according to the format string and write\n\
2186 the packed bytes into the writable buffer buf starting at offset. Note\n\
2187 that the offset is a required argument. See help(struct) for more\n\
2188 on format strings.");
2189
2190 static PyObject *
pack_into(PyObject * self,PyObject * const * args,Py_ssize_t nargs)2191 pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2192 {
2193 PyObject *s_object = NULL;
2194 PyObject *format, *result;
2195
2196 if (nargs == 0) {
2197 PyErr_SetString(PyExc_TypeError, "missing format argument");
2198 return NULL;
2199 }
2200 format = args[0];
2201
2202 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
2203 return NULL;
2204 }
2205 result = s_pack_into(s_object, args + 1, nargs - 1);
2206 Py_DECREF(s_object);
2207 return result;
2208 }
2209
2210 /*[clinic input]
2211 unpack
2212
2213 format as s_object: cache_struct
2214 buffer: Py_buffer
2215 /
2216
2217 Return a tuple containing values unpacked according to the format string.
2218
2219 The buffer's size in bytes must be calcsize(format).
2220
2221 See help(struct) for more on format strings.
2222 [clinic start generated code]*/
2223
2224 static PyObject *
unpack_impl(PyObject * module,PyStructObject * s_object,Py_buffer * buffer)2225 unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2226 /*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
2227 {
2228 return Struct_unpack_impl(s_object, buffer);
2229 }
2230
2231 /*[clinic input]
2232 unpack_from
2233
2234 format as s_object: cache_struct
2235 /
2236 buffer: Py_buffer
2237 offset: Py_ssize_t = 0
2238
2239 Return a tuple containing values unpacked according to the format string.
2240
2241 The buffer's size, minus offset, must be at least calcsize(format).
2242
2243 See help(struct) for more on format strings.
2244 [clinic start generated code]*/
2245
2246 static PyObject *
unpack_from_impl(PyObject * module,PyStructObject * s_object,Py_buffer * buffer,Py_ssize_t offset)2247 unpack_from_impl(PyObject *module, PyStructObject *s_object,
2248 Py_buffer *buffer, Py_ssize_t offset)
2249 /*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
2250 {
2251 return Struct_unpack_from_impl(s_object, buffer, offset);
2252 }
2253
2254 /*[clinic input]
2255 iter_unpack
2256
2257 format as s_object: cache_struct
2258 buffer: object
2259 /
2260
2261 Return an iterator yielding tuples unpacked from the given bytes.
2262
2263 The bytes are unpacked according to the format string, like
2264 a repeated invocation of unpack_from().
2265
2266 Requires that the bytes length be a multiple of the format struct size.
2267 [clinic start generated code]*/
2268
2269 static PyObject *
iter_unpack_impl(PyObject * module,PyStructObject * s_object,PyObject * buffer)2270 iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2271 PyObject *buffer)
2272 /*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
2273 {
2274 return Struct_iter_unpack(s_object, buffer);
2275 }
2276
2277 static struct PyMethodDef module_functions[] = {
2278 _CLEARCACHE_METHODDEF
2279 CALCSIZE_METHODDEF
2280 ITER_UNPACK_METHODDEF
2281 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2282 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
2283 UNPACK_METHODDEF
2284 UNPACK_FROM_METHODDEF
2285 {NULL, NULL} /* sentinel */
2286 };
2287
2288
2289 /* Module initialization */
2290
2291 PyDoc_STRVAR(module_doc,
2292 "Functions to convert between Python values and C structs.\n\
2293 Python bytes objects are used to hold the data representing the C struct\n\
2294 and also as format strings (explained below) to describe the layout of data\n\
2295 in the C struct.\n\
2296 \n\
2297 The optional first format char indicates byte order, size and alignment:\n\
2298 @: native order, size & alignment (default)\n\
2299 =: native order, std. size & alignment\n\
2300 <: little-endian, std. size & alignment\n\
2301 >: big-endian, std. size & alignment\n\
2302 !: same as >\n\
2303 \n\
2304 The remaining chars indicate types of args and must match exactly;\n\
2305 these can be preceded by a decimal repeat count:\n\
2306 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2307 ?: _Bool (requires C99; if not available, char is used instead)\n\
2308 h:short; H:unsigned short; i:int; I:unsigned int;\n\
2309 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
2310 Special cases (preceding decimal count indicates length):\n\
2311 s:string (array of char); p: pascal string (with count byte).\n\
2312 Special cases (only available in native format):\n\
2313 n:ssize_t; N:size_t;\n\
2314 P:an integer type that is wide enough to hold a pointer.\n\
2315 Special case (not in native mode unless 'long long' in platform C):\n\
2316 q:long long; Q:unsigned long long\n\
2317 Whitespace between formats is ignored.\n\
2318 \n\
2319 The variable struct.error is an exception raised on errors.\n");
2320
2321
2322 static int
_structmodule_traverse(PyObject * module,visitproc visit,void * arg)2323 _structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2324 {
2325 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2326 if (state) {
2327 Py_VISIT(state->PyStructType);
2328 Py_VISIT(state->unpackiter_type);
2329 Py_VISIT(state->StructError);
2330 }
2331 return 0;
2332 }
2333
2334 static int
_structmodule_clear(PyObject * module)2335 _structmodule_clear(PyObject *module)
2336 {
2337 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2338 if (state) {
2339 Py_CLEAR(state->PyStructType);
2340 Py_CLEAR(state->unpackiter_type);
2341 Py_CLEAR(state->StructError);
2342 }
2343 return 0;
2344 }
2345
2346 static void
_structmodule_free(void * module)2347 _structmodule_free(void *module)
2348 {
2349 _structmodule_clear((PyObject *)module);
2350 }
2351
2352 static struct PyModuleDef _structmodule = {
2353 PyModuleDef_HEAD_INIT,
2354 "_struct",
2355 module_doc,
2356 sizeof(_structmodulestate),
2357 module_functions,
2358 NULL,
2359 _structmodule_traverse,
2360 _structmodule_clear,
2361 _structmodule_free,
2362 };
2363
2364 PyMODINIT_FUNC
PyInit__struct(void)2365 PyInit__struct(void)
2366 {
2367 PyObject *m;
2368
2369 m = PyModule_Create(&_structmodule);
2370 if (m == NULL)
2371 return NULL;
2372
2373 PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec);
2374 if (PyStructType == NULL) {
2375 return NULL;
2376 }
2377 Py_INCREF(PyStructType);
2378 PyModule_AddObject(m, "Struct", PyStructType);
2379 get_struct_state(m)->PyStructType = PyStructType;
2380
2381 PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec);
2382 if (unpackiter_type == NULL) {
2383 return NULL;
2384 }
2385 get_struct_state(m)->unpackiter_type = unpackiter_type;
2386
2387 /* Check endian and swap in faster functions */
2388 {
2389 const formatdef *native = native_table;
2390 formatdef *other, *ptr;
2391 #if PY_LITTLE_ENDIAN
2392 other = lilendian_table;
2393 #else
2394 other = bigendian_table;
2395 #endif
2396 /* Scan through the native table, find a matching
2397 entry in the endian table and swap in the
2398 native implementations whenever possible
2399 (64-bit platforms may not have "standard" sizes) */
2400 while (native->format != '\0' && other->format != '\0') {
2401 ptr = other;
2402 while (ptr->format != '\0') {
2403 if (ptr->format == native->format) {
2404 /* Match faster when formats are
2405 listed in the same order */
2406 if (ptr == other)
2407 other++;
2408 /* Only use the trick if the
2409 size matches */
2410 if (ptr->size != native->size)
2411 break;
2412 /* Skip float and double, could be
2413 "unknown" float format */
2414 if (ptr->format == 'd' || ptr->format == 'f')
2415 break;
2416 /* Skip _Bool, semantics are different for standard size */
2417 if (ptr->format == '?')
2418 break;
2419 ptr->pack = native->pack;
2420 ptr->unpack = native->unpack;
2421 break;
2422 }
2423 ptr++;
2424 }
2425 native++;
2426 }
2427 }
2428
2429 /* Add some symbolic constants to the module */
2430 PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL);
2431 if (StructError == NULL)
2432 return NULL;
2433 Py_INCREF(StructError);
2434 PyModule_AddObject(m, "error", StructError);
2435 get_struct_state(m)->StructError = StructError;
2436
2437 return m;
2438 }
2439