• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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