• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (!PyInt_Check(v) && !PyLong_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 (!PyInt_Check(v) && !PyLong_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(PyInt_Check(v) || PyLong_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     *p = (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     if (get_long(v, &x) < 0)
818         return -1;
819     i = f->size;
820     if (i != SIZEOF_LONG) {
821         if ((i == 2) && (x < -32768 || x > 32767))
822             return _range_error(f, 0);
823 #if (SIZEOF_LONG != 4)
824         else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
825             return _range_error(f, 0);
826 #endif
827     }
828     do {
829         p[--i] = (char)x;
830         x >>= 8;
831     } while (i > 0);
832     return 0;
833 }
834 
835 static int
bp_uint(char * p,PyObject * v,const formatdef * f)836 bp_uint(char *p, PyObject *v, const formatdef *f)
837 {
838     unsigned long x;
839     Py_ssize_t i;
840     if (get_ulong(v, &x) < 0)
841         return -1;
842     i = f->size;
843     if (i != SIZEOF_LONG) {
844         unsigned long maxint = 1;
845         maxint <<= (unsigned long)(i * 8);
846         if (x >= maxint)
847             return _range_error(f, 1);
848     }
849     do {
850         p[--i] = (char)x;
851         x >>= 8;
852     } while (i > 0);
853     return 0;
854 }
855 
856 static int
bp_longlong(char * p,PyObject * v,const formatdef * f)857 bp_longlong(char *p, PyObject *v, const formatdef *f)
858 {
859     int res;
860     v = get_pylong(v);
861     if (v == NULL)
862         return -1;
863     res = _PyLong_AsByteArray((PyLongObject *)v,
864                               (unsigned char *)p,
865                               8,
866                               0, /* little_endian */
867                   1  /* signed */);
868     Py_DECREF(v);
869     return res;
870 }
871 
872 static int
bp_ulonglong(char * p,PyObject * v,const formatdef * f)873 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
874 {
875     int res;
876     v = get_pylong(v);
877     if (v == NULL)
878         return -1;
879     res = _PyLong_AsByteArray((PyLongObject *)v,
880                               (unsigned char *)p,
881                               8,
882                               0, /* little_endian */
883                   0  /* signed */);
884     Py_DECREF(v);
885     return res;
886 }
887 
888 static int
bp_float(char * p,PyObject * v,const formatdef * f)889 bp_float(char *p, PyObject *v, const formatdef *f)
890 {
891     double x = PyFloat_AsDouble(v);
892     if (x == -1 && PyErr_Occurred()) {
893         PyErr_SetString(StructError,
894                         "required argument is not a float");
895         return -1;
896     }
897     return _PyFloat_Pack4(x, (unsigned char *)p, 0);
898 }
899 
900 static int
bp_double(char * p,PyObject * v,const formatdef * f)901 bp_double(char *p, PyObject *v, const formatdef *f)
902 {
903     double x = PyFloat_AsDouble(v);
904     if (x == -1 && PyErr_Occurred()) {
905         PyErr_SetString(StructError,
906                         "required argument is not a float");
907         return -1;
908     }
909     return _PyFloat_Pack8(x, (unsigned char *)p, 0);
910 }
911 
912 static int
bp_bool(char * p,PyObject * v,const formatdef * f)913 bp_bool(char *p, PyObject *v, const formatdef *f)
914 {
915     int y;
916     y = PyObject_IsTrue(v);
917     if (y < 0)
918         return -1;
919     *p = (char)y;
920     return 0;
921 }
922 
923 static formatdef bigendian_table[] = {
924     {'x',       1,              0,              NULL},
925     {'b',       1,              0,              nu_byte,        np_byte},
926     {'B',       1,              0,              nu_ubyte,       np_ubyte},
927     {'c',       1,              0,              nu_char,        np_char},
928     {'s',       1,              0,              NULL},
929     {'p',       1,              0,              NULL},
930     {'h',       2,              0,              bu_int,         bp_int},
931     {'H',       2,              0,              bu_uint,        bp_uint},
932     {'i',       4,              0,              bu_int,         bp_int},
933     {'I',       4,              0,              bu_uint,        bp_uint},
934     {'l',       4,              0,              bu_int,         bp_int},
935     {'L',       4,              0,              bu_uint,        bp_uint},
936     {'q',       8,              0,              bu_longlong,    bp_longlong},
937     {'Q',       8,              0,              bu_ulonglong,   bp_ulonglong},
938     {'?',       1,              0,              bu_bool,        bp_bool},
939     {'f',       4,              0,              bu_float,       bp_float},
940     {'d',       8,              0,              bu_double,      bp_double},
941     {0}
942 };
943 
944 /* Little-endian routines. *****************************************************/
945 
946 static PyObject *
lu_int(const char * p,const formatdef * f)947 lu_int(const char *p, const formatdef *f)
948 {
949     long x = 0;
950     Py_ssize_t i = f->size;
951     const unsigned char *bytes = (const unsigned char *)p;
952     do {
953         x = (x<<8) | bytes[--i];
954     } while (i > 0);
955     /* Extend the sign bit. */
956     if (SIZEOF_LONG > f->size)
957         x |= -(x & (1L << ((8 * f->size) - 1)));
958     return PyInt_FromLong(x);
959 }
960 
961 static PyObject *
lu_uint(const char * p,const formatdef * f)962 lu_uint(const char *p, const formatdef *f)
963 {
964     unsigned long x = 0;
965     Py_ssize_t i = f->size;
966     const unsigned char *bytes = (const unsigned char *)p;
967     do {
968         x = (x<<8) | bytes[--i];
969     } while (i > 0);
970     if (x <= LONG_MAX)
971         return PyInt_FromLong((long)x);
972     return PyLong_FromUnsignedLong((long)x);
973 }
974 
975 static PyObject *
lu_longlong(const char * p,const formatdef * f)976 lu_longlong(const char *p, const formatdef *f)
977 {
978 #ifdef HAVE_LONG_LONG
979     PY_LONG_LONG x = 0;
980     Py_ssize_t i = f->size;
981     const unsigned char *bytes = (const unsigned char *)p;
982     do {
983         x = (x<<8) | bytes[--i];
984     } while (i > 0);
985     /* Extend the sign bit. */
986     if (SIZEOF_LONG_LONG > f->size)
987         x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
988     if (x >= LONG_MIN && x <= LONG_MAX)
989         return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
990     return PyLong_FromLongLong(x);
991 #else
992     return _PyLong_FromByteArray((const unsigned char *)p,
993                                   8,
994                                   1, /* little-endian */
995                       1  /* signed */);
996 #endif
997 }
998 
999 static PyObject *
lu_ulonglong(const char * p,const formatdef * f)1000 lu_ulonglong(const char *p, const formatdef *f)
1001 {
1002 #ifdef HAVE_LONG_LONG
1003     unsigned PY_LONG_LONG x = 0;
1004     Py_ssize_t i = f->size;
1005     const unsigned char *bytes = (const unsigned char *)p;
1006     do {
1007         x = (x<<8) | bytes[--i];
1008     } while (i > 0);
1009     if (x <= LONG_MAX)
1010         return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1011     return PyLong_FromUnsignedLongLong(x);
1012 #else
1013     return _PyLong_FromByteArray((const unsigned char *)p,
1014                                   8,
1015                                   1, /* little-endian */
1016                       0  /* signed */);
1017 #endif
1018 }
1019 
1020 static PyObject *
lu_float(const char * p,const formatdef * f)1021 lu_float(const char *p, const formatdef *f)
1022 {
1023     return unpack_float(p, 1);
1024 }
1025 
1026 static PyObject *
lu_double(const char * p,const formatdef * f)1027 lu_double(const char *p, const formatdef *f)
1028 {
1029     return unpack_double(p, 1);
1030 }
1031 
1032 static int
lp_int(char * p,PyObject * v,const formatdef * f)1033 lp_int(char *p, PyObject *v, const formatdef *f)
1034 {
1035     long x;
1036     Py_ssize_t i;
1037     if (get_long(v, &x) < 0)
1038         return -1;
1039     i = f->size;
1040     if (i != SIZEOF_LONG) {
1041         if ((i == 2) && (x < -32768 || x > 32767))
1042             return _range_error(f, 0);
1043 #if (SIZEOF_LONG != 4)
1044         else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1045             return _range_error(f, 0);
1046 #endif
1047     }
1048     do {
1049         *p++ = (char)x;
1050         x >>= 8;
1051     } while (--i > 0);
1052     return 0;
1053 }
1054 
1055 static int
lp_uint(char * p,PyObject * v,const formatdef * f)1056 lp_uint(char *p, PyObject *v, const formatdef *f)
1057 {
1058     unsigned long x;
1059     Py_ssize_t i;
1060     if (get_ulong(v, &x) < 0)
1061         return -1;
1062     i = f->size;
1063     if (i != SIZEOF_LONG) {
1064         unsigned long maxint = 1;
1065         maxint <<= (unsigned long)(i * 8);
1066         if (x >= maxint)
1067             return _range_error(f, 1);
1068     }
1069     do {
1070         *p++ = (char)x;
1071         x >>= 8;
1072     } while (--i > 0);
1073     return 0;
1074 }
1075 
1076 static int
lp_longlong(char * p,PyObject * v,const formatdef * f)1077 lp_longlong(char *p, PyObject *v, const formatdef *f)
1078 {
1079     int res;
1080     v = get_pylong(v);
1081     if (v == NULL)
1082         return -1;
1083     res = _PyLong_AsByteArray((PyLongObject*)v,
1084                               (unsigned char *)p,
1085                               8,
1086                               1, /* little_endian */
1087                   1  /* signed */);
1088     Py_DECREF(v);
1089     return res;
1090 }
1091 
1092 static int
lp_ulonglong(char * p,PyObject * v,const formatdef * f)1093 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1094 {
1095     int res;
1096     v = get_pylong(v);
1097     if (v == NULL)
1098         return -1;
1099     res = _PyLong_AsByteArray((PyLongObject*)v,
1100                               (unsigned char *)p,
1101                               8,
1102                               1, /* little_endian */
1103                   0  /* signed */);
1104     Py_DECREF(v);
1105     return res;
1106 }
1107 
1108 static int
lp_float(char * p,PyObject * v,const formatdef * f)1109 lp_float(char *p, PyObject *v, const formatdef *f)
1110 {
1111     double x = PyFloat_AsDouble(v);
1112     if (x == -1 && PyErr_Occurred()) {
1113         PyErr_SetString(StructError,
1114                         "required argument is not a float");
1115         return -1;
1116     }
1117     return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1118 }
1119 
1120 static int
lp_double(char * p,PyObject * v,const formatdef * f)1121 lp_double(char *p, PyObject *v, const formatdef *f)
1122 {
1123     double x = PyFloat_AsDouble(v);
1124     if (x == -1 && PyErr_Occurred()) {
1125         PyErr_SetString(StructError,
1126                         "required argument is not a float");
1127         return -1;
1128     }
1129     return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1130 }
1131 
1132 static formatdef lilendian_table[] = {
1133     {'x',       1,              0,              NULL},
1134     {'b',       1,              0,              nu_byte,        np_byte},
1135     {'B',       1,              0,              nu_ubyte,       np_ubyte},
1136     {'c',       1,              0,              nu_char,        np_char},
1137     {'s',       1,              0,              NULL},
1138     {'p',       1,              0,              NULL},
1139     {'h',       2,              0,              lu_int,         lp_int},
1140     {'H',       2,              0,              lu_uint,        lp_uint},
1141     {'i',       4,              0,              lu_int,         lp_int},
1142     {'I',       4,              0,              lu_uint,        lp_uint},
1143     {'l',       4,              0,              lu_int,         lp_int},
1144     {'L',       4,              0,              lu_uint,        lp_uint},
1145     {'q',       8,              0,              lu_longlong,    lp_longlong},
1146     {'Q',       8,              0,              lu_ulonglong,   lp_ulonglong},
1147     {'?',       1,              0,              bu_bool,        bp_bool}, /* Std rep not endian dep,
1148         but potentially different from native rep -- reuse bx_bool funcs. */
1149     {'f',       4,              0,              lu_float,       lp_float},
1150     {'d',       8,              0,              lu_double,      lp_double},
1151     {0}
1152 };
1153 
1154 
1155 static const formatdef *
whichtable(char ** pfmt)1156 whichtable(char **pfmt)
1157 {
1158     const char *fmt = (*pfmt)++; /* May be backed out of later */
1159     switch (*fmt) {
1160     case '<':
1161         return lilendian_table;
1162     case '>':
1163     case '!': /* Network byte order is big-endian */
1164         return bigendian_table;
1165     case '=': { /* Host byte order -- different from native in alignment! */
1166         int n = 1;
1167         char *p = (char *) &n;
1168         if (*p == 1)
1169             return lilendian_table;
1170         else
1171             return bigendian_table;
1172     }
1173     default:
1174         --*pfmt; /* Back out of pointer increment */
1175         /* Fall through */
1176     case '@':
1177         return native_table;
1178     }
1179 }
1180 
1181 
1182 /* Get the table entry for a format code */
1183 
1184 static const formatdef *
getentry(int c,const formatdef * f)1185 getentry(int c, const formatdef *f)
1186 {
1187     for (; f->format != '\0'; f++) {
1188         if (f->format == c) {
1189             return f;
1190         }
1191     }
1192     PyErr_SetString(StructError, "bad char in struct format");
1193     return NULL;
1194 }
1195 
1196 
1197 /* Align a size according to a format code.  Return -1 on overflow. */
1198 
1199 static Py_ssize_t
align(Py_ssize_t size,char c,const formatdef * e)1200 align(Py_ssize_t size, char c, const formatdef *e)
1201 {
1202     Py_ssize_t extra;
1203 
1204     if (e->format == c) {
1205         if (e->alignment && size > 0) {
1206             extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1207             if (extra > PY_SSIZE_T_MAX - size)
1208                 return -1;
1209             size += extra;
1210         }
1211     }
1212     return size;
1213 }
1214 
1215 
1216 /* calculate the size of a format string */
1217 
1218 static int
prepare_s(PyStructObject * self)1219 prepare_s(PyStructObject *self)
1220 {
1221     const formatdef *f;
1222     const formatdef *e;
1223     formatcode *codes;
1224 
1225     const char *s;
1226     const char *fmt;
1227     char c;
1228     Py_ssize_t size, len, num, itemsize;
1229 
1230     fmt = PyString_AS_STRING(self->s_format);
1231 
1232     f = whichtable((char **)&fmt);
1233 
1234     s = fmt;
1235     size = 0;
1236     len = 0;
1237     while ((c = *s++) != '\0') {
1238         if (isspace(Py_CHARMASK(c)))
1239             continue;
1240         if ('0' <= c && c <= '9') {
1241             num = c - '0';
1242             while ('0' <= (c = *s++) && c <= '9') {
1243                 /* overflow-safe version of
1244                    if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1245                 if (num >= PY_SSIZE_T_MAX / 10 && (
1246                         num > PY_SSIZE_T_MAX / 10 ||
1247                         (c - '0') > PY_SSIZE_T_MAX % 10))
1248                     goto overflow;
1249                 num = num*10 + (c - '0');
1250             }
1251             if (c == '\0')
1252                 break;
1253         }
1254         else
1255             num = 1;
1256 
1257         e = getentry(c, f);
1258         if (e == NULL)
1259             return -1;
1260 
1261         switch (c) {
1262             case 's': /* fall through */
1263             case 'p': len++; break;
1264             case 'x': break;
1265             default: len += num; break;
1266         }
1267 
1268         itemsize = e->size;
1269         size = align(size, c, e);
1270         if (size == -1)
1271             goto overflow;
1272 
1273         /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1274         if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1275             goto overflow;
1276         size += num * itemsize;
1277     }
1278 
1279     /* check for overflow */
1280     if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1281         PyErr_NoMemory();
1282         return -1;
1283     }
1284 
1285     self->s_size = size;
1286     self->s_len = len;
1287     codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1288     if (codes == NULL) {
1289         PyErr_NoMemory();
1290         return -1;
1291     }
1292     /* Free any s_codes value left over from a previous initialization. */
1293     if (self->s_codes != NULL)
1294         PyMem_FREE(self->s_codes);
1295     self->s_codes = codes;
1296 
1297     s = fmt;
1298     size = 0;
1299     while ((c = *s++) != '\0') {
1300         if (isspace(Py_CHARMASK(c)))
1301             continue;
1302         if ('0' <= c && c <= '9') {
1303             num = c - '0';
1304             while ('0' <= (c = *s++) && c <= '9')
1305                 num = num*10 + (c - '0');
1306             if (c == '\0')
1307                 break;
1308         }
1309         else
1310             num = 1;
1311 
1312         e = getentry(c, f);
1313 
1314         size = align(size, c, e);
1315         if (c == 's' || c == 'p') {
1316             codes->offset = size;
1317             codes->size = num;
1318             codes->fmtdef = e;
1319             codes++;
1320             size += num;
1321         } else if (c == 'x') {
1322             size += num;
1323         } else {
1324             while (--num >= 0) {
1325                 codes->offset = size;
1326                 codes->size = e->size;
1327                 codes->fmtdef = e;
1328                 codes++;
1329                 size += e->size;
1330             }
1331         }
1332     }
1333     codes->fmtdef = NULL;
1334     codes->offset = size;
1335     codes->size = 0;
1336 
1337     return 0;
1338 
1339   overflow:
1340     PyErr_SetString(StructError,
1341                     "total struct size too long");
1342     return -1;
1343 }
1344 
1345 static PyObject *
s_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1346 s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1347 {
1348     PyObject *self;
1349 
1350     assert(type != NULL && type->tp_alloc != NULL);
1351 
1352     self = type->tp_alloc(type, 0);
1353     if (self != NULL) {
1354         PyStructObject *s = (PyStructObject*)self;
1355         Py_INCREF(Py_None);
1356         s->s_format = Py_None;
1357         s->s_codes = NULL;
1358         s->s_size = -1;
1359         s->s_len = -1;
1360     }
1361     return self;
1362 }
1363 
1364 static int
s_init(PyObject * self,PyObject * args,PyObject * kwds)1365 s_init(PyObject *self, PyObject *args, PyObject *kwds)
1366 {
1367     PyStructObject *soself = (PyStructObject *)self;
1368     PyObject *o_format = NULL;
1369     int ret = 0;
1370     static char *kwlist[] = {"format", 0};
1371 
1372     assert(PyStruct_Check(self));
1373 
1374     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
1375                                      &o_format))
1376         return -1;
1377 
1378     if (PyString_Check(o_format)) {
1379         Py_INCREF(o_format);
1380         Py_XSETREF(soself->s_format, o_format);
1381     }
1382     else if (PyUnicode_Check(o_format)) {
1383         PyObject *str = PyUnicode_AsEncodedString(o_format, "ascii", NULL);
1384         if (str == NULL)
1385             return -1;
1386         Py_XSETREF(soself->s_format, str);
1387     }
1388     else {
1389         PyErr_Format(PyExc_TypeError,
1390                      "Struct() argument 1 must be string, not %s",
1391                      Py_TYPE(o_format)->tp_name);
1392         return -1;
1393     }
1394 
1395     ret = prepare_s(soself);
1396     return ret;
1397 }
1398 
1399 static void
s_dealloc(PyStructObject * s)1400 s_dealloc(PyStructObject *s)
1401 {
1402     if (s->weakreflist != NULL)
1403         PyObject_ClearWeakRefs((PyObject *)s);
1404     if (s->s_codes != NULL) {
1405         PyMem_FREE(s->s_codes);
1406     }
1407     Py_XDECREF(s->s_format);
1408     Py_TYPE(s)->tp_free((PyObject *)s);
1409 }
1410 
1411 static PyObject *
s_unpack_internal(PyStructObject * soself,char * startfrom)1412 s_unpack_internal(PyStructObject *soself, char *startfrom) {
1413     formatcode *code;
1414     Py_ssize_t i = 0;
1415     PyObject *result = PyTuple_New(soself->s_len);
1416     if (result == NULL)
1417         return NULL;
1418 
1419     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1420         PyObject *v;
1421         const formatdef *e = code->fmtdef;
1422         const char *res = startfrom + code->offset;
1423         if (e->format == 's') {
1424             v = PyString_FromStringAndSize(res, code->size);
1425         } else if (e->format == 'p') {
1426             Py_ssize_t n = *(unsigned char*)res;
1427             if (n >= code->size)
1428                 n = code->size - 1;
1429             v = PyString_FromStringAndSize(res + 1, n);
1430         } else {
1431             v = e->unpack(res, e);
1432         }
1433         if (v == NULL)
1434             goto fail;
1435         PyTuple_SET_ITEM(result, i++, v);
1436     }
1437 
1438     return result;
1439 fail:
1440     Py_DECREF(result);
1441     return NULL;
1442 }
1443 
1444 
1445 PyDoc_STRVAR(s_unpack__doc__,
1446 "S.unpack(str) -> (v1, v2, ...)\n\
1447 \n\
1448 Return tuple containing values unpacked according to this Struct's format.\n\
1449 Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1450 strings.");
1451 
1452 static PyObject *
s_unpack(PyObject * self,PyObject * inputstr)1453 s_unpack(PyObject *self, PyObject *inputstr)
1454 {
1455     Py_buffer buf;
1456     char *start;
1457     Py_ssize_t len;
1458     PyObject *args=NULL, *result;
1459     PyStructObject *soself = (PyStructObject *)self;
1460     assert(PyStruct_Check(self));
1461     assert(soself->s_codes != NULL);
1462     if (inputstr == NULL)
1463         goto fail;
1464     if (PyString_Check(inputstr) &&
1465         PyString_GET_SIZE(inputstr) == soself->s_size) {
1466             return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1467     }
1468     args = PyTuple_Pack(1, inputstr);
1469     if (args == NULL)
1470         return NULL;
1471     if (!PyArg_ParseTuple(args, "s*:unpack", &buf))
1472         goto fail;
1473     start = buf.buf;
1474     len = buf.len;
1475     if (soself->s_size != len) {
1476         PyBuffer_Release(&buf);
1477         goto fail;
1478     }
1479     result = s_unpack_internal(soself, start);
1480     Py_DECREF(args);
1481     PyBuffer_Release(&buf);
1482     return result;
1483 
1484 fail:
1485     Py_XDECREF(args);
1486     PyErr_Format(StructError,
1487         "unpack requires a string argument of length %zd",
1488         soself->s_size);
1489     return NULL;
1490 }
1491 
1492 PyDoc_STRVAR(s_unpack_from__doc__,
1493 "S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1494 \n\
1495 Return tuple containing values unpacked according to this Struct's format.\n\
1496 Unlike unpack, unpack_from can unpack values from any object supporting\n\
1497 the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1498 See struct.__doc__ for more on format strings.");
1499 
1500 static PyObject *
s_unpack_from(PyObject * self,PyObject * args,PyObject * kwds)1501 s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1502 {
1503     static char *kwlist[] = {"buffer", "offset", 0};
1504     static char *fmt = "z*|n:unpack_from";
1505     Py_buffer buf;
1506     Py_ssize_t buffer_len = 0, offset = 0;
1507     char *buffer = NULL;
1508     PyStructObject *soself = (PyStructObject *)self;
1509     PyObject *result;
1510     assert(PyStruct_Check(self));
1511     assert(soself->s_codes != NULL);
1512 
1513     if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1514                                      &buf, &offset))
1515         return NULL;
1516     buffer = buf.buf;
1517     buffer_len = buf.len;
1518     if (buffer == NULL) {
1519         PyErr_Format(StructError,
1520             "unpack_from requires a buffer argument");
1521         PyBuffer_Release(&buf);
1522         return NULL;
1523     }
1524 
1525     if (offset < 0)
1526         offset += buffer_len;
1527 
1528     if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1529         PyErr_Format(StructError,
1530             "unpack_from requires a buffer of at least %zd bytes",
1531             soself->s_size);
1532         PyBuffer_Release(&buf);
1533         return NULL;
1534     }
1535     result = s_unpack_internal(soself, buffer + offset);
1536     PyBuffer_Release(&buf);
1537     return result;
1538 }
1539 
1540 
1541 /*
1542  * Guts of the pack function.
1543  *
1544  * Takes a struct object, a tuple of arguments, and offset in that tuple of
1545  * argument for where to start processing the arguments for packing, and a
1546  * character buffer for writing the packed string.  The caller must insure
1547  * that the buffer may contain the required length for packing the arguments.
1548  * 0 is returned on success, 1 is returned if there is an error.
1549  *
1550  */
1551 static int
s_pack_internal(PyStructObject * soself,PyObject * args,int offset,char * buf)1552 s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1553 {
1554     formatcode *code;
1555     /* XXX(nnorwitz): why does i need to be a local?  can we use
1556        the offset parameter or do we need the wider width? */
1557     Py_ssize_t i;
1558 
1559     memset(buf, '\0', soself->s_size);
1560     i = offset;
1561     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1562         Py_ssize_t n;
1563         PyObject *v = PyTuple_GET_ITEM(args, i++);
1564         const formatdef *e = code->fmtdef;
1565         char *res = buf + code->offset;
1566         if (e->format == 's') {
1567             if (!PyString_Check(v)) {
1568                 PyErr_SetString(StructError,
1569                                 "argument for 's' must "
1570                                 "be a string");
1571                 return -1;
1572             }
1573             n = PyString_GET_SIZE(v);
1574             if (n > code->size)
1575                 n = code->size;
1576             if (n > 0)
1577                 memcpy(res, PyString_AS_STRING(v), n);
1578         } else if (e->format == 'p') {
1579             if (!PyString_Check(v)) {
1580                 PyErr_SetString(StructError,
1581                                 "argument for 'p' must "
1582                                 "be a string");
1583                 return -1;
1584             }
1585             n = PyString_GET_SIZE(v);
1586             if (n > (code->size - 1))
1587                 n = code->size - 1;
1588             if (n > 0)
1589                 memcpy(res + 1, PyString_AS_STRING(v), n);
1590             if (n > 255)
1591                 n = 255;
1592             *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1593         } else if (e->pack(res, v, e) < 0) {
1594             if (strchr(integer_codes, e->format) != NULL &&
1595                 PyErr_ExceptionMatches(PyExc_OverflowError))
1596                 PyErr_Format(StructError,
1597                              "integer out of range for "
1598                              "'%c' format code",
1599                              e->format);
1600             return -1;
1601         }
1602     }
1603 
1604     /* Success */
1605     return 0;
1606 }
1607 
1608 
1609 PyDoc_STRVAR(s_pack__doc__,
1610 "S.pack(v1, v2, ...) -> string\n\
1611 \n\
1612 Return a string containing values v1, v2, ... packed according to this\n\
1613 Struct's format. See struct.__doc__ for more on format strings.");
1614 
1615 static PyObject *
s_pack(PyObject * self,PyObject * args)1616 s_pack(PyObject *self, PyObject *args)
1617 {
1618     PyStructObject *soself;
1619     PyObject *result;
1620 
1621     /* Validate arguments. */
1622     soself = (PyStructObject *)self;
1623     assert(PyStruct_Check(self));
1624     assert(soself->s_codes != NULL);
1625     if (PyTuple_GET_SIZE(args) != soself->s_len)
1626     {
1627         PyErr_Format(StructError,
1628             "pack expected %zd items for packing (got %zd)", soself->s_len, PyTuple_GET_SIZE(args));
1629         return NULL;
1630     }
1631 
1632     /* Allocate a new string */
1633     result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1634     if (result == NULL)
1635         return NULL;
1636 
1637     /* Call the guts */
1638     if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1639         Py_DECREF(result);
1640         return NULL;
1641     }
1642 
1643     return result;
1644 }
1645 
1646 PyDoc_STRVAR(s_pack_into__doc__,
1647 "S.pack_into(buffer, offset, v1, v2, ...)\n\
1648 \n\
1649 Pack the values v1, v2, ... according to this Struct's format, write \n\
1650 the packed bytes into the writable buffer buf starting at offset.  Note\n\
1651 that the offset is not an optional argument.  See struct.__doc__ for \n\
1652 more on format strings.");
1653 
1654 static PyObject *
s_pack_into(PyObject * self,PyObject * args)1655 s_pack_into(PyObject *self, PyObject *args)
1656 {
1657     PyStructObject *soself;
1658     Py_buffer buf;
1659     Py_ssize_t offset;
1660 
1661     /* Validate arguments.  +1 is for the first arg as buffer. */
1662     soself = (PyStructObject *)self;
1663     assert(PyStruct_Check(self));
1664     assert(soself->s_codes != NULL);
1665     if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1666     {
1667         if (PyTuple_GET_SIZE(args) == 0) {
1668             PyErr_Format(StructError,
1669                         "pack_into expected buffer argument");
1670         }
1671         else if (PyTuple_GET_SIZE(args) == 1) {
1672             PyErr_Format(StructError,
1673                         "pack_into expected offset argument");
1674         }
1675         else {
1676             PyErr_Format(StructError,
1677                         "pack_into expected %zd items for packing (got %zd)",
1678                         soself->s_len, (PyTuple_GET_SIZE(args) - 2));
1679         }
1680         return NULL;
1681     }
1682 
1683     /* Extract a writable memory buffer from the first argument */
1684     if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buf))
1685         return NULL;
1686 
1687     /* Extract the offset from the first argument */
1688     offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
1689     if (offset == -1 && PyErr_Occurred()) {
1690         PyBuffer_Release(&buf);
1691         return NULL;
1692     }
1693 
1694     /* Support negative offsets. */
1695     if (offset < 0)
1696         offset += buf.len;
1697 
1698     /* Check boundaries */
1699     if (offset < 0 || (buf.len - offset) < soself->s_size) {
1700         PyErr_Format(StructError,
1701                      "pack_into requires a buffer of at least %zd bytes",
1702                      soself->s_size);
1703         PyBuffer_Release(&buf);
1704         return NULL;
1705     }
1706 
1707     /* Call the guts */
1708     if (s_pack_internal(soself, args, 2, (char *)buf.buf + offset) != 0) {
1709         PyBuffer_Release(&buf);
1710         return NULL;
1711     }
1712     PyBuffer_Release(&buf);
1713 
1714     Py_RETURN_NONE;
1715 }
1716 
1717 static PyObject *
s_get_format(PyStructObject * self,void * unused)1718 s_get_format(PyStructObject *self, void *unused)
1719 {
1720     Py_INCREF(self->s_format);
1721     return self->s_format;
1722 }
1723 
1724 static PyObject *
s_get_size(PyStructObject * self,void * unused)1725 s_get_size(PyStructObject *self, void *unused)
1726 {
1727     return PyInt_FromSsize_t(self->s_size);
1728 }
1729 
1730 PyDoc_STRVAR(s_sizeof__doc__,
1731 "S.__sizeof__() -> size of S in memory, in bytes");
1732 
1733 static PyObject *
s_sizeof(PyStructObject * self,void * unused)1734 s_sizeof(PyStructObject *self, void *unused)
1735 {
1736     Py_ssize_t size;
1737 
1738     size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode) * (self->s_len + 1);
1739     return PyLong_FromSsize_t(size);
1740 }
1741 
1742 /* List of functions */
1743 
1744 static struct PyMethodDef s_methods[] = {
1745     {"pack",            s_pack,         METH_VARARGS, s_pack__doc__},
1746     {"pack_into",       s_pack_into,    METH_VARARGS, s_pack_into__doc__},
1747     {"unpack",          s_unpack,       METH_O, s_unpack__doc__},
1748     {"unpack_from",     (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
1749                     s_unpack_from__doc__},
1750     {"__sizeof__",      (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
1751     {NULL,       NULL}          /* sentinel */
1752 };
1753 
1754 PyDoc_STRVAR(s__doc__, "Compiled struct object");
1755 
1756 #define OFF(x) offsetof(PyStructObject, x)
1757 
1758 static PyGetSetDef s_getsetlist[] = {
1759     {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1760     {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1761     {NULL} /* sentinel */
1762 };
1763 
1764 static
1765 PyTypeObject PyStructType = {
1766     PyVarObject_HEAD_INIT(NULL, 0)
1767     "Struct",
1768     sizeof(PyStructObject),
1769     0,
1770     (destructor)s_dealloc,      /* tp_dealloc */
1771     0,                                          /* tp_print */
1772     0,                                          /* tp_getattr */
1773     0,                                          /* tp_setattr */
1774     0,                                          /* tp_compare */
1775     0,                                          /* tp_repr */
1776     0,                                          /* tp_as_number */
1777     0,                                          /* tp_as_sequence */
1778     0,                                          /* tp_as_mapping */
1779     0,                                          /* tp_hash */
1780     0,                                          /* tp_call */
1781     0,                                          /* tp_str */
1782     PyObject_GenericGetAttr,            /* tp_getattro */
1783     PyObject_GenericSetAttr,            /* tp_setattro */
1784     0,                                          /* tp_as_buffer */
1785     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1786     s__doc__,                           /* tp_doc */
1787     0,                                          /* tp_traverse */
1788     0,                                          /* tp_clear */
1789     0,                                          /* tp_richcompare */
1790     offsetof(PyStructObject, weakreflist),      /* tp_weaklistoffset */
1791     0,                                          /* tp_iter */
1792     0,                                          /* tp_iternext */
1793     s_methods,                          /* tp_methods */
1794     NULL,                               /* tp_members */
1795     s_getsetlist,               /* tp_getset */
1796     0,                                          /* tp_base */
1797     0,                                          /* tp_dict */
1798     0,                                          /* tp_descr_get */
1799     0,                                          /* tp_descr_set */
1800     0,                                          /* tp_dictoffset */
1801     s_init,                             /* tp_init */
1802     PyType_GenericAlloc,/* tp_alloc */
1803     s_new,                              /* tp_new */
1804     PyObject_Del,               /* tp_free */
1805 };
1806 
1807 
1808 /* ---- Standalone functions  ---- */
1809 
1810 #define MAXCACHE 100
1811 static PyObject *cache = NULL;
1812 
1813 static PyObject *
cache_struct(PyObject * fmt)1814 cache_struct(PyObject *fmt)
1815 {
1816     PyObject * s_object;
1817 
1818     if (cache == NULL) {
1819         cache = PyDict_New();
1820         if (cache == NULL)
1821             return NULL;
1822     }
1823 
1824     s_object = PyDict_GetItem(cache, fmt);
1825     if (s_object != NULL) {
1826         Py_INCREF(s_object);
1827         return s_object;
1828     }
1829 
1830     s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1831     if (s_object != NULL) {
1832         if (PyDict_Size(cache) >= MAXCACHE)
1833             PyDict_Clear(cache);
1834         /* Attempt to cache the result */
1835         if (PyDict_SetItem(cache, fmt, s_object) == -1)
1836             PyErr_Clear();
1837     }
1838     return s_object;
1839 }
1840 
1841 PyDoc_STRVAR(clearcache_doc,
1842 "Clear the internal cache.");
1843 
1844 static PyObject *
clearcache(PyObject * self)1845 clearcache(PyObject *self)
1846 {
1847     Py_CLEAR(cache);
1848     Py_RETURN_NONE;
1849 }
1850 
1851 PyDoc_STRVAR(calcsize_doc,
1852 "Return size of C struct described by format string fmt.");
1853 
1854 static PyObject *
calcsize(PyObject * self,PyObject * fmt)1855 calcsize(PyObject *self, PyObject *fmt)
1856 {
1857     Py_ssize_t n;
1858     PyObject *s_object = cache_struct(fmt);
1859     if (s_object == NULL)
1860         return NULL;
1861     n = ((PyStructObject *)s_object)->s_size;
1862     Py_DECREF(s_object);
1863     return PyInt_FromSsize_t(n);
1864 }
1865 
1866 PyDoc_STRVAR(pack_doc,
1867 "Return string containing values v1, v2, ... packed according to fmt.");
1868 
1869 static PyObject *
pack(PyObject * self,PyObject * args)1870 pack(PyObject *self, PyObject *args)
1871 {
1872     PyObject *s_object, *fmt, *newargs, *result;
1873     Py_ssize_t n = PyTuple_GET_SIZE(args);
1874 
1875     if (n == 0) {
1876         PyErr_SetString(PyExc_TypeError, "missing format argument");
1877         return NULL;
1878     }
1879     fmt = PyTuple_GET_ITEM(args, 0);
1880     newargs = PyTuple_GetSlice(args, 1, n);
1881     if (newargs == NULL)
1882         return NULL;
1883 
1884     s_object = cache_struct(fmt);
1885     if (s_object == NULL) {
1886         Py_DECREF(newargs);
1887         return NULL;
1888     }
1889     result = s_pack(s_object, newargs);
1890     Py_DECREF(newargs);
1891     Py_DECREF(s_object);
1892     return result;
1893 }
1894 
1895 PyDoc_STRVAR(pack_into_doc,
1896 "Pack the values v1, v2, ... according to fmt.\n\
1897 Write the packed bytes into the writable buffer buf starting at offset.");
1898 
1899 static PyObject *
pack_into(PyObject * self,PyObject * args)1900 pack_into(PyObject *self, PyObject *args)
1901 {
1902     PyObject *s_object, *fmt, *newargs, *result;
1903     Py_ssize_t n = PyTuple_GET_SIZE(args);
1904 
1905     if (n == 0) {
1906         PyErr_SetString(PyExc_TypeError, "missing format argument");
1907         return NULL;
1908     }
1909     fmt = PyTuple_GET_ITEM(args, 0);
1910     newargs = PyTuple_GetSlice(args, 1, n);
1911     if (newargs == NULL)
1912         return NULL;
1913 
1914     s_object = cache_struct(fmt);
1915     if (s_object == NULL) {
1916         Py_DECREF(newargs);
1917         return NULL;
1918     }
1919     result = s_pack_into(s_object, newargs);
1920     Py_DECREF(newargs);
1921     Py_DECREF(s_object);
1922     return result;
1923 }
1924 
1925 PyDoc_STRVAR(unpack_doc,
1926 "Unpack the string containing packed C structure data, according to fmt.\n\
1927 Requires len(string) == calcsize(fmt).");
1928 
1929 static PyObject *
unpack(PyObject * self,PyObject * args)1930 unpack(PyObject *self, PyObject *args)
1931 {
1932     PyObject *s_object, *fmt, *inputstr, *result;
1933 
1934     if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1935         return NULL;
1936 
1937     s_object = cache_struct(fmt);
1938     if (s_object == NULL)
1939         return NULL;
1940     result = s_unpack(s_object, inputstr);
1941     Py_DECREF(s_object);
1942     return result;
1943 }
1944 
1945 PyDoc_STRVAR(unpack_from_doc,
1946 "Unpack the buffer, containing packed C structure data, according to\n\
1947 fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
1948 
1949 static PyObject *
unpack_from(PyObject * self,PyObject * args,PyObject * kwds)1950 unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1951 {
1952     PyObject *s_object, *fmt, *newargs, *result;
1953     Py_ssize_t n = PyTuple_GET_SIZE(args);
1954 
1955     if (n == 0) {
1956         PyErr_SetString(PyExc_TypeError, "missing format argument");
1957         return NULL;
1958     }
1959     fmt = PyTuple_GET_ITEM(args, 0);
1960     newargs = PyTuple_GetSlice(args, 1, n);
1961     if (newargs == NULL)
1962         return NULL;
1963 
1964     s_object = cache_struct(fmt);
1965     if (s_object == NULL) {
1966         Py_DECREF(newargs);
1967         return NULL;
1968     }
1969     result = s_unpack_from(s_object, newargs, kwds);
1970     Py_DECREF(newargs);
1971     Py_DECREF(s_object);
1972     return result;
1973 }
1974 
1975 static struct PyMethodDef module_functions[] = {
1976     {"_clearcache",     (PyCFunction)clearcache,        METH_NOARGS,    clearcache_doc},
1977     {"calcsize",        calcsize,       METH_O, calcsize_doc},
1978     {"pack",            pack,           METH_VARARGS,   pack_doc},
1979     {"pack_into",       pack_into,      METH_VARARGS,   pack_into_doc},
1980     {"unpack",          unpack, METH_VARARGS,   unpack_doc},
1981     {"unpack_from",     (PyCFunction)unpack_from,
1982                     METH_VARARGS|METH_KEYWORDS,         unpack_from_doc},
1983     {NULL,       NULL}          /* sentinel */
1984 };
1985 
1986 
1987 /* Module initialization */
1988 
1989 PyDoc_STRVAR(module_doc,
1990 "Functions to convert between Python values and C structs represented\n\
1991 as Python strings. It uses format strings (explained below) as compact\n\
1992 descriptions of the lay-out of the C structs and the intended conversion\n\
1993 to/from Python values.\n\
1994 \n\
1995 The optional first format char indicates byte order, size and alignment:\n\
1996   @: native order, size & alignment (default)\n\
1997   =: native order, std. size & alignment\n\
1998   <: little-endian, std. size & alignment\n\
1999   >: big-endian, std. size & alignment\n\
2000   !: same as >\n\
2001 \n\
2002 The remaining chars indicate types of args and must match exactly;\n\
2003 these can be preceded by a decimal repeat count:\n\
2004   x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2005   ?: _Bool (requires C99; if not available, char is used instead)\n\
2006   h:short; H:unsigned short; i:int; I:unsigned int;\n\
2007   l:long; L:unsigned long; f:float; d:double.\n\
2008 Special cases (preceding decimal count indicates length):\n\
2009   s:string (array of char); p: pascal string (with count byte).\n\
2010 Special case (only available in native format):\n\
2011   P:an integer type that is wide enough to hold a pointer.\n\
2012 Special case (not in native mode unless 'long long' in platform C):\n\
2013   q:long long; Q:unsigned long long\n\
2014 Whitespace between formats is ignored.\n\
2015 \n\
2016 The variable struct.error is an exception raised on errors.\n");
2017 
2018 PyMODINIT_FUNC
init_struct(void)2019 init_struct(void)
2020 {
2021     PyObject *ver, *m;
2022 
2023     ver = PyString_FromString("0.2");
2024     if (ver == NULL)
2025         return;
2026 
2027     m = Py_InitModule3("_struct", module_functions, module_doc);
2028     if (m == NULL)
2029         return;
2030 
2031     Py_TYPE(&PyStructType) = &PyType_Type;
2032     if (PyType_Ready(&PyStructType) < 0)
2033         return;
2034 
2035     /* This speed trick can't be used until overflow masking goes
2036        away, because native endian always raises exceptions
2037        instead of overflow masking. */
2038 
2039     /* Check endian and swap in faster functions */
2040     {
2041         int one = 1;
2042         formatdef *native = native_table;
2043         formatdef *other, *ptr;
2044         if ((int)*(unsigned char*)&one)
2045             other = lilendian_table;
2046         else
2047             other = bigendian_table;
2048         /* Scan through the native table, find a matching
2049            entry in the endian table and swap in the
2050            native implementations whenever possible
2051            (64-bit platforms may not have "standard" sizes) */
2052         while (native->format != '\0' && other->format != '\0') {
2053             ptr = other;
2054             while (ptr->format != '\0') {
2055                 if (ptr->format == native->format) {
2056                     /* Match faster when formats are
2057                        listed in the same order */
2058                     if (ptr == other)
2059                         other++;
2060                     /* Only use the trick if the
2061                        size matches */
2062                     if (ptr->size != native->size)
2063                         break;
2064                     /* Skip float and double, could be
2065                        "unknown" float format */
2066                     if (ptr->format == 'd' || ptr->format == 'f')
2067                         break;
2068                     ptr->pack = native->pack;
2069                     ptr->unpack = native->unpack;
2070                     break;
2071                 }
2072                 ptr++;
2073             }
2074             native++;
2075         }
2076     }
2077 
2078     /* Add some symbolic constants to the module */
2079     if (StructError == NULL) {
2080         StructError = PyErr_NewException("struct.error", NULL, NULL);
2081         if (StructError == NULL)
2082             return;
2083     }
2084 
2085     Py_INCREF(StructError);
2086     PyModule_AddObject(m, "error", StructError);
2087 
2088     Py_INCREF((PyObject*)&PyStructType);
2089     PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
2090 
2091     PyModule_AddObject(m, "__version__", ver);
2092 
2093     PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
2094     PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
2095 }
2096