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