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