• 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"
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 *, PyObject **);
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 
1289     f = whichtable(&fmt);
1290 
1291     s = fmt;
1292     size = 0;
1293     len = 0;
1294     ncodes = 0;
1295     while ((c = *s++) != '\0') {
1296         if (Py_ISSPACE(Py_CHARMASK(c)))
1297             continue;
1298         if ('0' <= c && c <= '9') {
1299             num = c - '0';
1300             while ('0' <= (c = *s++) && c <= '9') {
1301                 /* overflow-safe version of
1302                    if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1303                 if (num >= PY_SSIZE_T_MAX / 10 && (
1304                         num > PY_SSIZE_T_MAX / 10 ||
1305                         (c - '0') > PY_SSIZE_T_MAX % 10))
1306                     goto overflow;
1307                 num = num*10 + (c - '0');
1308             }
1309             if (c == '\0') {
1310                 PyErr_SetString(StructError,
1311                                 "repeat count given without format specifier");
1312                 return -1;
1313             }
1314         }
1315         else
1316             num = 1;
1317 
1318         e = getentry(c, f);
1319         if (e == NULL)
1320             return -1;
1321 
1322         switch (c) {
1323             case 's': /* fall through */
1324             case 'p': len++; ncodes++; break;
1325             case 'x': break;
1326             default: len += num; if (num) ncodes++; break;
1327         }
1328 
1329         itemsize = e->size;
1330         size = align(size, c, e);
1331         if (size == -1)
1332             goto overflow;
1333 
1334         /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1335         if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1336             goto overflow;
1337         size += num * itemsize;
1338     }
1339 
1340     /* check for overflow */
1341     if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
1342         PyErr_NoMemory();
1343         return -1;
1344     }
1345 
1346     self->s_size = size;
1347     self->s_len = len;
1348     codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
1349     if (codes == NULL) {
1350         PyErr_NoMemory();
1351         return -1;
1352     }
1353     /* Free any s_codes value left over from a previous initialization. */
1354     if (self->s_codes != NULL)
1355         PyMem_FREE(self->s_codes);
1356     self->s_codes = codes;
1357 
1358     s = fmt;
1359     size = 0;
1360     while ((c = *s++) != '\0') {
1361         if (Py_ISSPACE(Py_CHARMASK(c)))
1362             continue;
1363         if ('0' <= c && c <= '9') {
1364             num = c - '0';
1365             while ('0' <= (c = *s++) && c <= '9')
1366                 num = num*10 + (c - '0');
1367         }
1368         else
1369             num = 1;
1370 
1371         e = getentry(c, f);
1372 
1373         size = align(size, c, e);
1374         if (c == 's' || c == 'p') {
1375             codes->offset = size;
1376             codes->size = num;
1377             codes->fmtdef = e;
1378             codes->repeat = 1;
1379             codes++;
1380             size += num;
1381         } else if (c == 'x') {
1382             size += num;
1383         } else if (num) {
1384             codes->offset = size;
1385             codes->size = e->size;
1386             codes->fmtdef = e;
1387             codes->repeat = num;
1388             codes++;
1389             size += e->size * num;
1390         }
1391     }
1392     codes->fmtdef = NULL;
1393     codes->offset = size;
1394     codes->size = 0;
1395     codes->repeat = 0;
1396 
1397     return 0;
1398 
1399   overflow:
1400     PyErr_SetString(StructError,
1401                     "total struct size too long");
1402     return -1;
1403 }
1404 
1405 static PyObject *
s_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1406 s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1407 {
1408     PyObject *self;
1409 
1410     assert(type != NULL && type->tp_alloc != NULL);
1411 
1412     self = type->tp_alloc(type, 0);
1413     if (self != NULL) {
1414         PyStructObject *s = (PyStructObject*)self;
1415         Py_INCREF(Py_None);
1416         s->s_format = Py_None;
1417         s->s_codes = NULL;
1418         s->s_size = -1;
1419         s->s_len = -1;
1420     }
1421     return self;
1422 }
1423 
1424 /*[clinic input]
1425 Struct.__init__
1426 
1427     format: object
1428 
1429 Create a compiled struct object.
1430 
1431 Return a new Struct object which writes and reads binary data according to
1432 the format string.
1433 
1434 See help(struct) for more on format strings.
1435 [clinic start generated code]*/
1436 
1437 static int
Struct___init___impl(PyStructObject * self,PyObject * format)1438 Struct___init___impl(PyStructObject *self, PyObject *format)
1439 /*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
1440 {
1441     int ret = 0;
1442 
1443     if (PyUnicode_Check(format)) {
1444         format = PyUnicode_AsASCIIString(format);
1445         if (format == NULL)
1446             return -1;
1447     }
1448     /* XXX support buffer interface, too */
1449     else {
1450         Py_INCREF(format);
1451     }
1452 
1453     if (!PyBytes_Check(format)) {
1454         Py_DECREF(format);
1455         PyErr_Format(PyExc_TypeError,
1456                      "Struct() argument 1 must be a str or bytes object, "
1457                      "not %.200s",
1458                      Py_TYPE(format)->tp_name);
1459         return -1;
1460     }
1461 
1462     Py_SETREF(self->s_format, format);
1463 
1464     ret = prepare_s(self);
1465     return ret;
1466 }
1467 
1468 static void
s_dealloc(PyStructObject * s)1469 s_dealloc(PyStructObject *s)
1470 {
1471     if (s->weakreflist != NULL)
1472         PyObject_ClearWeakRefs((PyObject *)s);
1473     if (s->s_codes != NULL) {
1474         PyMem_FREE(s->s_codes);
1475     }
1476     Py_DECREF(s->s_format);
1477     Py_TYPE(s)->tp_free((PyObject *)s);
1478 }
1479 
1480 static PyObject *
s_unpack_internal(PyStructObject * soself,const char * startfrom)1481 s_unpack_internal(PyStructObject *soself, const char *startfrom) {
1482     formatcode *code;
1483     Py_ssize_t i = 0;
1484     PyObject *result = PyTuple_New(soself->s_len);
1485     if (result == NULL)
1486         return NULL;
1487 
1488     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1489         const formatdef *e = code->fmtdef;
1490         const char *res = startfrom + code->offset;
1491         Py_ssize_t j = code->repeat;
1492         while (j--) {
1493             PyObject *v;
1494             if (e->format == 's') {
1495                 v = PyBytes_FromStringAndSize(res, code->size);
1496             } else if (e->format == 'p') {
1497                 Py_ssize_t n = *(unsigned char*)res;
1498                 if (n >= code->size)
1499                     n = code->size - 1;
1500                 v = PyBytes_FromStringAndSize(res + 1, n);
1501             } else {
1502                 v = e->unpack(res, e);
1503             }
1504             if (v == NULL)
1505                 goto fail;
1506             PyTuple_SET_ITEM(result, i++, v);
1507             res += code->size;
1508         }
1509     }
1510 
1511     return result;
1512 fail:
1513     Py_DECREF(result);
1514     return NULL;
1515 }
1516 
1517 
1518 /*[clinic input]
1519 Struct.unpack
1520 
1521     buffer: Py_buffer
1522     /
1523 
1524 Return a tuple containing unpacked values.
1525 
1526 Unpack according to the format string Struct.format. The buffer's size
1527 in bytes must be Struct.size.
1528 
1529 See help(struct) for more on format strings.
1530 [clinic start generated code]*/
1531 
1532 static PyObject *
Struct_unpack_impl(PyStructObject * self,Py_buffer * buffer)1533 Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1534 /*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
1535 {
1536     assert(self->s_codes != NULL);
1537     if (buffer->len != self->s_size) {
1538         PyErr_Format(StructError,
1539                      "unpack requires a buffer of %zd bytes",
1540                      self->s_size);
1541         return NULL;
1542     }
1543     return s_unpack_internal(self, buffer->buf);
1544 }
1545 
1546 /*[clinic input]
1547 Struct.unpack_from
1548 
1549     buffer: Py_buffer
1550     offset: Py_ssize_t = 0
1551 
1552 Return a tuple containing unpacked values.
1553 
1554 Values are unpacked according to the format string Struct.format.
1555 
1556 The buffer's size in bytes, minus offset, must be at least Struct.size.
1557 
1558 See help(struct) for more on format strings.
1559 [clinic start generated code]*/
1560 
1561 static PyObject *
Struct_unpack_from_impl(PyStructObject * self,Py_buffer * buffer,Py_ssize_t offset)1562 Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1563                         Py_ssize_t offset)
1564 /*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/
1565 {
1566     assert(self->s_codes != NULL);
1567 
1568     if (offset < 0)
1569         offset += buffer->len;
1570     if (offset < 0 || buffer->len - offset < self->s_size) {
1571         PyErr_Format(StructError,
1572             "unpack_from requires a buffer of at least %zd bytes",
1573             self->s_size);
1574         return NULL;
1575     }
1576     return s_unpack_internal(self, (char*)buffer->buf + offset);
1577 }
1578 
1579 
1580 
1581 /* Unpack iterator type */
1582 
1583 typedef struct {
1584     PyObject_HEAD
1585     PyStructObject *so;
1586     Py_buffer buf;
1587     Py_ssize_t index;
1588 } unpackiterobject;
1589 
1590 static void
unpackiter_dealloc(unpackiterobject * self)1591 unpackiter_dealloc(unpackiterobject *self)
1592 {
1593     /* bpo-31095: UnTrack is needed before calling any callbacks */
1594     PyObject_GC_UnTrack(self);
1595     Py_XDECREF(self->so);
1596     PyBuffer_Release(&self->buf);
1597     PyObject_GC_Del(self);
1598 }
1599 
1600 static int
unpackiter_traverse(unpackiterobject * self,visitproc visit,void * arg)1601 unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1602 {
1603     Py_VISIT(self->so);
1604     Py_VISIT(self->buf.obj);
1605     return 0;
1606 }
1607 
1608 static PyObject *
unpackiter_len(unpackiterobject * self)1609 unpackiter_len(unpackiterobject *self)
1610 {
1611     Py_ssize_t len;
1612     if (self->so == NULL)
1613         len = 0;
1614     else
1615         len = (self->buf.len - self->index) / self->so->s_size;
1616     return PyLong_FromSsize_t(len);
1617 }
1618 
1619 static PyMethodDef unpackiter_methods[] = {
1620     {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1621     {NULL,              NULL}           /* sentinel */
1622 };
1623 
1624 static PyObject *
unpackiter_iternext(unpackiterobject * self)1625 unpackiter_iternext(unpackiterobject *self)
1626 {
1627     PyObject *result;
1628     if (self->so == NULL)
1629         return NULL;
1630     if (self->index >= self->buf.len) {
1631         /* Iterator exhausted */
1632         Py_CLEAR(self->so);
1633         PyBuffer_Release(&self->buf);
1634         return NULL;
1635     }
1636     assert(self->index + self->so->s_size <= self->buf.len);
1637     result = s_unpack_internal(self->so,
1638                                (char*) self->buf.buf + self->index);
1639     self->index += self->so->s_size;
1640     return result;
1641 }
1642 
1643 static PyTypeObject unpackiter_type = {
1644     PyVarObject_HEAD_INIT(NULL, 0)
1645     "unpack_iterator",                          /* tp_name */
1646     sizeof(unpackiterobject),                   /* tp_basicsize */
1647     0,                                          /* tp_itemsize */
1648     (destructor)unpackiter_dealloc,             /* tp_dealloc */
1649     0,                                          /* tp_print */
1650     0,                                          /* tp_getattr */
1651     0,                                          /* tp_setattr */
1652     0,                                          /* tp_reserved */
1653     0,                                          /* tp_repr */
1654     0,                                          /* tp_as_number */
1655     0,                                          /* tp_as_sequence */
1656     0,                                          /* tp_as_mapping */
1657     0,                                          /* tp_hash */
1658     0,                                          /* tp_call */
1659     0,                                          /* tp_str */
1660     PyObject_GenericGetAttr,                    /* tp_getattro */
1661     0,                                          /* tp_setattro */
1662     0,                                          /* tp_as_buffer */
1663     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
1664     0,                                          /* tp_doc */
1665     (traverseproc)unpackiter_traverse,          /* tp_traverse */
1666     0,                                          /* tp_clear */
1667     0,                                          /* tp_richcompare */
1668     0,                                          /* tp_weaklistoffset */
1669     PyObject_SelfIter,                          /* tp_iter */
1670     (iternextfunc)unpackiter_iternext,          /* tp_iternext */
1671     unpackiter_methods                          /* tp_methods */
1672 };
1673 
1674 /*[clinic input]
1675 Struct.iter_unpack
1676 
1677     buffer: object
1678     /
1679 
1680 Return an iterator yielding tuples.
1681 
1682 Tuples are unpacked from the given bytes source, like a repeated
1683 invocation of unpack_from().
1684 
1685 Requires that the bytes length be a multiple of the struct size.
1686 [clinic start generated code]*/
1687 
1688 static PyObject *
Struct_iter_unpack(PyStructObject * self,PyObject * buffer)1689 Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1690 /*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
1691 {
1692     unpackiterobject *iter;
1693 
1694     assert(self->s_codes != NULL);
1695 
1696     if (self->s_size == 0) {
1697         PyErr_Format(StructError,
1698                      "cannot iteratively unpack with a struct of length 0");
1699         return NULL;
1700     }
1701 
1702     iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1703     if (iter == NULL)
1704         return NULL;
1705 
1706     if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1707         Py_DECREF(iter);
1708         return NULL;
1709     }
1710     if (iter->buf.len % self->s_size != 0) {
1711         PyErr_Format(StructError,
1712                      "iterative unpacking requires a buffer of "
1713                      "a multiple of %zd bytes",
1714                      self->s_size);
1715         Py_DECREF(iter);
1716         return NULL;
1717     }
1718     Py_INCREF(self);
1719     iter->so = self;
1720     iter->index = 0;
1721     return (PyObject *)iter;
1722 }
1723 
1724 
1725 /*
1726  * Guts of the pack function.
1727  *
1728  * Takes a struct object, a tuple of arguments, and offset in that tuple of
1729  * argument for where to start processing the arguments for packing, and a
1730  * character buffer for writing the packed string.  The caller must insure
1731  * that the buffer may contain the required length for packing the arguments.
1732  * 0 is returned on success, 1 is returned if there is an error.
1733  *
1734  */
1735 static int
s_pack_internal(PyStructObject * soself,PyObject * const * args,int offset,char * buf)1736 s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
1737 {
1738     formatcode *code;
1739     /* XXX(nnorwitz): why does i need to be a local?  can we use
1740        the offset parameter or do we need the wider width? */
1741     Py_ssize_t i;
1742 
1743     memset(buf, '\0', soself->s_size);
1744     i = offset;
1745     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1746         const formatdef *e = code->fmtdef;
1747         char *res = buf + code->offset;
1748         Py_ssize_t j = code->repeat;
1749         while (j--) {
1750             PyObject *v = args[i++];
1751             if (e->format == 's') {
1752                 Py_ssize_t n;
1753                 int isstring;
1754                 void *p;
1755                 isstring = PyBytes_Check(v);
1756                 if (!isstring && !PyByteArray_Check(v)) {
1757                     PyErr_SetString(StructError,
1758                                     "argument for 's' must be a bytes object");
1759                     return -1;
1760                 }
1761                 if (isstring) {
1762                     n = PyBytes_GET_SIZE(v);
1763                     p = PyBytes_AS_STRING(v);
1764                 }
1765                 else {
1766                     n = PyByteArray_GET_SIZE(v);
1767                     p = PyByteArray_AS_STRING(v);
1768                 }
1769                 if (n > code->size)
1770                     n = code->size;
1771                 if (n > 0)
1772                     memcpy(res, p, n);
1773             } else if (e->format == 'p') {
1774                 Py_ssize_t n;
1775                 int isstring;
1776                 void *p;
1777                 isstring = PyBytes_Check(v);
1778                 if (!isstring && !PyByteArray_Check(v)) {
1779                     PyErr_SetString(StructError,
1780                                     "argument for 'p' must be a bytes object");
1781                     return -1;
1782                 }
1783                 if (isstring) {
1784                     n = PyBytes_GET_SIZE(v);
1785                     p = PyBytes_AS_STRING(v);
1786                 }
1787                 else {
1788                     n = PyByteArray_GET_SIZE(v);
1789                     p = PyByteArray_AS_STRING(v);
1790                 }
1791                 if (n > (code->size - 1))
1792                     n = code->size - 1;
1793                 if (n > 0)
1794                     memcpy(res + 1, p, n);
1795                 if (n > 255)
1796                     n = 255;
1797                 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1798             } else {
1799                 if (e->pack(res, v, e) < 0) {
1800                     if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1801                         PyErr_SetString(StructError,
1802                                         "int too large to convert");
1803                     return -1;
1804                 }
1805             }
1806             res += code->size;
1807         }
1808     }
1809 
1810     /* Success */
1811     return 0;
1812 }
1813 
1814 
1815 PyDoc_STRVAR(s_pack__doc__,
1816 "S.pack(v1, v2, ...) -> bytes\n\
1817 \n\
1818 Return a bytes object containing values v1, v2, ... packed according\n\
1819 to the format string S.format.  See help(struct) for more on format\n\
1820 strings.");
1821 
1822 static PyObject *
s_pack(PyObject * self,PyObject * const * args,Py_ssize_t nargs)1823 s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1824 {
1825     PyStructObject *soself;
1826     PyObject *result;
1827 
1828     /* Validate arguments. */
1829     soself = (PyStructObject *)self;
1830     assert(PyStruct_Check(self));
1831     assert(soself->s_codes != NULL);
1832     if (nargs != soself->s_len)
1833     {
1834         PyErr_Format(StructError,
1835             "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1836         return NULL;
1837     }
1838 
1839     /* Allocate a new buffer */
1840     result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1841     if (result == NULL)
1842         return NULL;
1843 
1844     /* Call the guts */
1845     if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1846         Py_DECREF(result);
1847         return NULL;
1848     }
1849 
1850     return result;
1851 }
1852 
1853 PyDoc_STRVAR(s_pack_into__doc__,
1854 "S.pack_into(buffer, offset, v1, v2, ...)\n\
1855 \n\
1856 Pack the values v1, v2, ... according to the format string S.format\n\
1857 and write the packed bytes into the writable buffer buf starting at\n\
1858 offset.  Note that the offset is a required argument.  See\n\
1859 help(struct) for more on format strings.");
1860 
1861 static PyObject *
s_pack_into(PyObject * self,PyObject * const * args,Py_ssize_t nargs)1862 s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1863 {
1864     PyStructObject *soself;
1865     Py_buffer buffer;
1866     Py_ssize_t offset;
1867 
1868     /* Validate arguments.  +1 is for the first arg as buffer. */
1869     soself = (PyStructObject *)self;
1870     assert(PyStruct_Check(self));
1871     assert(soself->s_codes != NULL);
1872     if (nargs != (soself->s_len + 2))
1873     {
1874         if (nargs == 0) {
1875             PyErr_Format(StructError,
1876                         "pack_into expected buffer argument");
1877         }
1878         else if (nargs == 1) {
1879             PyErr_Format(StructError,
1880                         "pack_into expected offset argument");
1881         }
1882         else {
1883             PyErr_Format(StructError,
1884                         "pack_into expected %zd items for packing (got %zd)",
1885                         soself->s_len, (nargs - 2));
1886         }
1887         return NULL;
1888     }
1889 
1890     /* Extract a writable memory buffer from the first argument */
1891     if (!PyArg_Parse(args[0], "w*", &buffer))
1892         return NULL;
1893     assert(buffer.len >= 0);
1894 
1895     /* Extract the offset from the first argument */
1896     offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
1897     if (offset == -1 && PyErr_Occurred()) {
1898         PyBuffer_Release(&buffer);
1899         return NULL;
1900     }
1901 
1902     /* Support negative offsets. */
1903     if (offset < 0) {
1904          /* Check that negative offset is low enough to fit data */
1905         if (offset + soself->s_size > 0) {
1906             PyErr_Format(StructError,
1907                          "no space to pack %zd bytes at offset %zd",
1908                          soself->s_size,
1909                          offset);
1910             PyBuffer_Release(&buffer);
1911             return NULL;
1912         }
1913 
1914         /* Check that negative offset is not crossing buffer boundary */
1915         if (offset + buffer.len < 0) {
1916             PyErr_Format(StructError,
1917                          "offset %zd out of range for %zd-byte buffer",
1918                          offset,
1919                          buffer.len);
1920             PyBuffer_Release(&buffer);
1921             return NULL;
1922         }
1923 
1924         offset += buffer.len;
1925     }
1926 
1927     /* Check boundaries */
1928     if ((buffer.len - offset) < soself->s_size) {
1929         assert(offset >= 0);
1930         assert(soself->s_size >= 0);
1931 
1932         PyErr_Format(StructError,
1933                      "pack_into requires a buffer of at least %zu bytes for "
1934                      "packing %zd bytes at offset %zd "
1935                      "(actual buffer size is %zd)",
1936                      (size_t)soself->s_size + (size_t)offset,
1937                      soself->s_size,
1938                      offset,
1939                      buffer.len);
1940         PyBuffer_Release(&buffer);
1941         return NULL;
1942     }
1943 
1944     /* Call the guts */
1945     if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1946         PyBuffer_Release(&buffer);
1947         return NULL;
1948     }
1949 
1950     PyBuffer_Release(&buffer);
1951     Py_RETURN_NONE;
1952 }
1953 
1954 static PyObject *
s_get_format(PyStructObject * self,void * unused)1955 s_get_format(PyStructObject *self, void *unused)
1956 {
1957     return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1958                                        PyBytes_GET_SIZE(self->s_format));
1959 }
1960 
1961 static PyObject *
s_get_size(PyStructObject * self,void * unused)1962 s_get_size(PyStructObject *self, void *unused)
1963 {
1964     return PyLong_FromSsize_t(self->s_size);
1965 }
1966 
1967 PyDoc_STRVAR(s_sizeof__doc__,
1968 "S.__sizeof__() -> size of S in memory, in bytes");
1969 
1970 static PyObject *
s_sizeof(PyStructObject * self,void * unused)1971 s_sizeof(PyStructObject *self, void *unused)
1972 {
1973     Py_ssize_t size;
1974     formatcode *code;
1975 
1976     size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
1977     for (code = self->s_codes; code->fmtdef != NULL; code++)
1978         size += sizeof(formatcode);
1979     return PyLong_FromSsize_t(size);
1980 }
1981 
1982 /* List of functions */
1983 
1984 static struct PyMethodDef s_methods[] = {
1985     STRUCT_ITER_UNPACK_METHODDEF
1986     {"pack",            (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
1987     {"pack_into",       (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
1988     STRUCT_UNPACK_METHODDEF
1989     STRUCT_UNPACK_FROM_METHODDEF
1990     {"__sizeof__",      (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
1991     {NULL,       NULL}          /* sentinel */
1992 };
1993 
1994 #define OFF(x) offsetof(PyStructObject, x)
1995 
1996 static PyGetSetDef s_getsetlist[] = {
1997     {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1998     {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1999     {NULL} /* sentinel */
2000 };
2001 
2002 static
2003 PyTypeObject PyStructType = {
2004     PyVarObject_HEAD_INIT(NULL, 0)
2005     "Struct",
2006     sizeof(PyStructObject),
2007     0,
2008     (destructor)s_dealloc,      /* tp_dealloc */
2009     0,                                          /* tp_print */
2010     0,                                          /* tp_getattr */
2011     0,                                          /* tp_setattr */
2012     0,                                          /* tp_reserved */
2013     0,                                          /* tp_repr */
2014     0,                                          /* tp_as_number */
2015     0,                                          /* tp_as_sequence */
2016     0,                                          /* tp_as_mapping */
2017     0,                                          /* tp_hash */
2018     0,                                          /* tp_call */
2019     0,                                          /* tp_str */
2020     PyObject_GenericGetAttr,                    /* tp_getattro */
2021     PyObject_GenericSetAttr,                    /* tp_setattro */
2022     0,                                          /* tp_as_buffer */
2023     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
2024     Struct___init____doc__,                     /* tp_doc */
2025     0,                                          /* tp_traverse */
2026     0,                                          /* tp_clear */
2027     0,                                          /* tp_richcompare */
2028     offsetof(PyStructObject, weakreflist),      /* tp_weaklistoffset */
2029     0,                                          /* tp_iter */
2030     0,                                          /* tp_iternext */
2031     s_methods,                                  /* tp_methods */
2032     NULL,                                       /* tp_members */
2033     s_getsetlist,                               /* tp_getset */
2034     0,                                          /* tp_base */
2035     0,                                          /* tp_dict */
2036     0,                                          /* tp_descr_get */
2037     0,                                          /* tp_descr_set */
2038     0,                                          /* tp_dictoffset */
2039     Struct___init__,                            /* tp_init */
2040     PyType_GenericAlloc,                        /* tp_alloc */
2041     s_new,                                      /* tp_new */
2042     PyObject_Del,                               /* tp_free */
2043 };
2044 
2045 
2046 /* ---- Standalone functions  ---- */
2047 
2048 #define MAXCACHE 100
2049 static PyObject *cache = NULL;
2050 
2051 static int
cache_struct_converter(PyObject * fmt,PyObject ** ptr)2052 cache_struct_converter(PyObject *fmt, PyObject **ptr)
2053 {
2054     PyObject * s_object;
2055 
2056     if (fmt == NULL) {
2057         Py_DECREF(*ptr);
2058         *ptr = NULL;
2059         return 1;
2060     }
2061 
2062     if (cache == NULL) {
2063         cache = PyDict_New();
2064         if (cache == NULL)
2065             return 0;
2066     }
2067 
2068     s_object = PyDict_GetItem(cache, fmt);
2069     if (s_object != NULL) {
2070         Py_INCREF(s_object);
2071         *ptr = s_object;
2072         return Py_CLEANUP_SUPPORTED;
2073     }
2074 
2075     s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
2076     if (s_object != NULL) {
2077         if (PyDict_GET_SIZE(cache) >= MAXCACHE)
2078             PyDict_Clear(cache);
2079         /* Attempt to cache the result */
2080         if (PyDict_SetItem(cache, fmt, s_object) == -1)
2081             PyErr_Clear();
2082         *ptr = s_object;
2083         return Py_CLEANUP_SUPPORTED;
2084     }
2085     return 0;
2086 }
2087 
2088 /*[clinic input]
2089 _clearcache
2090 
2091 Clear the internal cache.
2092 [clinic start generated code]*/
2093 
2094 static PyObject *
_clearcache_impl(PyObject * module)2095 _clearcache_impl(PyObject *module)
2096 /*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
2097 {
2098     Py_CLEAR(cache);
2099     Py_RETURN_NONE;
2100 }
2101 
2102 
2103 /*[clinic input]
2104 calcsize -> Py_ssize_t
2105 
2106     format as s_object: cache_struct
2107     /
2108 
2109 Return size in bytes of the struct described by the format string.
2110 [clinic start generated code]*/
2111 
2112 static Py_ssize_t
calcsize_impl(PyObject * module,PyStructObject * s_object)2113 calcsize_impl(PyObject *module, PyStructObject *s_object)
2114 /*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
2115 {
2116     return s_object->s_size;
2117 }
2118 
2119 PyDoc_STRVAR(pack_doc,
2120 "pack(format, v1, v2, ...) -> bytes\n\
2121 \n\
2122 Return a bytes object containing the values v1, v2, ... packed according\n\
2123 to the format string.  See help(struct) for more on format strings.");
2124 
2125 static PyObject *
pack(PyObject * self,PyObject * const * args,Py_ssize_t nargs)2126 pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2127 {
2128     PyObject *s_object = NULL;
2129     PyObject *format, *result;
2130 
2131     if (nargs == 0) {
2132         PyErr_SetString(PyExc_TypeError, "missing format argument");
2133         return NULL;
2134     }
2135     format = args[0];
2136 
2137     if (!cache_struct_converter(format, &s_object)) {
2138         return NULL;
2139     }
2140     result = s_pack(s_object, args + 1, nargs - 1);
2141     Py_DECREF(s_object);
2142     return result;
2143 }
2144 
2145 PyDoc_STRVAR(pack_into_doc,
2146 "pack_into(format, buffer, offset, v1, v2, ...)\n\
2147 \n\
2148 Pack the values v1, v2, ... according to the format string and write\n\
2149 the packed bytes into the writable buffer buf starting at offset.  Note\n\
2150 that the offset is a required argument.  See help(struct) for more\n\
2151 on format strings.");
2152 
2153 static PyObject *
pack_into(PyObject * self,PyObject * const * args,Py_ssize_t nargs)2154 pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2155 {
2156     PyObject *s_object = NULL;
2157     PyObject *format, *result;
2158 
2159     if (nargs == 0) {
2160         PyErr_SetString(PyExc_TypeError, "missing format argument");
2161         return NULL;
2162     }
2163     format = args[0];
2164 
2165     if (!cache_struct_converter(format, &s_object)) {
2166         return NULL;
2167     }
2168     result = s_pack_into(s_object, args + 1, nargs - 1);
2169     Py_DECREF(s_object);
2170     return result;
2171 }
2172 
2173 /*[clinic input]
2174 unpack
2175 
2176     format as s_object: cache_struct
2177     buffer: Py_buffer
2178     /
2179 
2180 Return a tuple containing values unpacked according to the format string.
2181 
2182 The buffer's size in bytes must be calcsize(format).
2183 
2184 See help(struct) for more on format strings.
2185 [clinic start generated code]*/
2186 
2187 static PyObject *
unpack_impl(PyObject * module,PyStructObject * s_object,Py_buffer * buffer)2188 unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2189 /*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
2190 {
2191     return Struct_unpack_impl(s_object, buffer);
2192 }
2193 
2194 /*[clinic input]
2195 unpack_from
2196 
2197     format as s_object: cache_struct
2198     /
2199     buffer: Py_buffer
2200     offset: Py_ssize_t = 0
2201 
2202 Return a tuple containing values unpacked according to the format string.
2203 
2204 The buffer's size, minus offset, must be at least calcsize(format).
2205 
2206 See help(struct) for more on format strings.
2207 [clinic start generated code]*/
2208 
2209 static PyObject *
unpack_from_impl(PyObject * module,PyStructObject * s_object,Py_buffer * buffer,Py_ssize_t offset)2210 unpack_from_impl(PyObject *module, PyStructObject *s_object,
2211                  Py_buffer *buffer, Py_ssize_t offset)
2212 /*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
2213 {
2214     return Struct_unpack_from_impl(s_object, buffer, offset);
2215 }
2216 
2217 /*[clinic input]
2218 iter_unpack
2219 
2220     format as s_object: cache_struct
2221     buffer: object
2222     /
2223 
2224 Return an iterator yielding tuples unpacked from the given bytes.
2225 
2226 The bytes are unpacked according to the format string, like
2227 a repeated invocation of unpack_from().
2228 
2229 Requires that the bytes length be a multiple of the format struct size.
2230 [clinic start generated code]*/
2231 
2232 static PyObject *
iter_unpack_impl(PyObject * module,PyStructObject * s_object,PyObject * buffer)2233 iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2234                  PyObject *buffer)
2235 /*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
2236 {
2237     return Struct_iter_unpack(s_object, buffer);
2238 }
2239 
2240 static struct PyMethodDef module_functions[] = {
2241     _CLEARCACHE_METHODDEF
2242     CALCSIZE_METHODDEF
2243     ITER_UNPACK_METHODDEF
2244     {"pack",            (PyCFunction)pack, METH_FASTCALL,   pack_doc},
2245     {"pack_into",       (PyCFunction)pack_into, METH_FASTCALL,   pack_into_doc},
2246     UNPACK_METHODDEF
2247     UNPACK_FROM_METHODDEF
2248     {NULL,       NULL}          /* sentinel */
2249 };
2250 
2251 
2252 /* Module initialization */
2253 
2254 PyDoc_STRVAR(module_doc,
2255 "Functions to convert between Python values and C structs.\n\
2256 Python bytes objects are used to hold the data representing the C struct\n\
2257 and also as format strings (explained below) to describe the layout of data\n\
2258 in the C struct.\n\
2259 \n\
2260 The optional first format char indicates byte order, size and alignment:\n\
2261   @: native order, size & alignment (default)\n\
2262   =: native order, std. size & alignment\n\
2263   <: little-endian, std. size & alignment\n\
2264   >: big-endian, std. size & alignment\n\
2265   !: same as >\n\
2266 \n\
2267 The remaining chars indicate types of args and must match exactly;\n\
2268 these can be preceded by a decimal repeat count:\n\
2269   x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2270   ?: _Bool (requires C99; if not available, char is used instead)\n\
2271   h:short; H:unsigned short; i:int; I:unsigned int;\n\
2272   l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
2273 Special cases (preceding decimal count indicates length):\n\
2274   s:string (array of char); p: pascal string (with count byte).\n\
2275 Special cases (only available in native format):\n\
2276   n:ssize_t; N:size_t;\n\
2277   P:an integer type that is wide enough to hold a pointer.\n\
2278 Special case (not in native mode unless 'long long' in platform C):\n\
2279   q:long long; Q:unsigned long long\n\
2280 Whitespace between formats is ignored.\n\
2281 \n\
2282 The variable struct.error is an exception raised on errors.\n");
2283 
2284 
2285 static struct PyModuleDef _structmodule = {
2286     PyModuleDef_HEAD_INIT,
2287     "_struct",
2288     module_doc,
2289     -1,
2290     module_functions,
2291     NULL,
2292     NULL,
2293     NULL,
2294     NULL
2295 };
2296 
2297 PyMODINIT_FUNC
PyInit__struct(void)2298 PyInit__struct(void)
2299 {
2300     PyObject *m;
2301 
2302     m = PyModule_Create(&_structmodule);
2303     if (m == NULL)
2304         return NULL;
2305 
2306     Py_TYPE(&PyStructType) = &PyType_Type;
2307     if (PyType_Ready(&PyStructType) < 0)
2308         return NULL;
2309 
2310     if (PyType_Ready(&unpackiter_type) < 0)
2311         return NULL;
2312 
2313     /* Check endian and swap in faster functions */
2314     {
2315         const formatdef *native = native_table;
2316         formatdef *other, *ptr;
2317 #if PY_LITTLE_ENDIAN
2318         other = lilendian_table;
2319 #else
2320         other = bigendian_table;
2321 #endif
2322         /* Scan through the native table, find a matching
2323            entry in the endian table and swap in the
2324            native implementations whenever possible
2325            (64-bit platforms may not have "standard" sizes) */
2326         while (native->format != '\0' && other->format != '\0') {
2327             ptr = other;
2328             while (ptr->format != '\0') {
2329                 if (ptr->format == native->format) {
2330                     /* Match faster when formats are
2331                        listed in the same order */
2332                     if (ptr == other)
2333                         other++;
2334                     /* Only use the trick if the
2335                        size matches */
2336                     if (ptr->size != native->size)
2337                         break;
2338                     /* Skip float and double, could be
2339                        "unknown" float format */
2340                     if (ptr->format == 'd' || ptr->format == 'f')
2341                         break;
2342                     ptr->pack = native->pack;
2343                     ptr->unpack = native->unpack;
2344                     break;
2345                 }
2346                 ptr++;
2347             }
2348             native++;
2349         }
2350     }
2351 
2352     /* Add some symbolic constants to the module */
2353     if (StructError == NULL) {
2354         StructError = PyErr_NewException("struct.error", NULL, NULL);
2355         if (StructError == NULL)
2356             return NULL;
2357     }
2358 
2359     Py_INCREF(StructError);
2360     PyModule_AddObject(m, "error", StructError);
2361 
2362     Py_INCREF((PyObject*)&PyStructType);
2363     PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
2364 
2365     return m;
2366 }
2367