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