Skip to content

Commit 8315ea5

Browse files
committed
Included assert.h in Python.h -- it's absurd that this basic tool of
good C practice hasn't been available to everything all along. Added Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) macro to pyport.h; this just casts VALUE from type WIDE to type NARROW, but assert-fails if Py_DEBUG is defined and info is lost due to casting. Replaced a line in Fredrik's fix to marshal.c to use the new macro.
1 parent e211071 commit 8315ea5

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

Include/Python.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
3131

3232
#include "patchlevel.h"
3333
#include "config.h"
34-
#include "pyport.h"
3534

3635
/* config.h may or may not define DL_IMPORT */
3736
#ifndef DL_IMPORT /* declarations for DLL import/export */
@@ -51,6 +50,9 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
5150
#ifdef HAVE_STDLIB_H
5251
#include <stdlib.h>
5352
#endif
53+
#include <assert.h>
54+
55+
#include "pyport.h"
5456

5557
#include "myproto.h"
5658

Include/pyport.h

+17
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ RETSIGTYPE
2727
Meaning: Expands to void or int, depending on what the platform wants
2828
signal handlers to return. Note that only void is ANSI!
2929
Used in: Py_RETURN_FROM_SIGNAL_HANDLER
30+
31+
Py_DEBUG
32+
Meaning: Extra checks compiled in for debug mode.
33+
Used in: Py_SAFE_DOWNCAST
3034
**************************************************************************/
3135

3236

@@ -74,6 +78,19 @@ extern "C" {
7478
#define Py_RETURN_FROM_SIGNAL_HANDLER(VALUE) \
7579
Py_FORCE_EXPANSION(RETSIGTYPE) ## _PySIGRETURN(VALUE)
7680

81+
/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)
82+
* Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this
83+
* assert-fails if any information is lost.
84+
* Caution:
85+
* VALUE may be evaluated more than once.
86+
*/
87+
#ifdef Py_DEBUG
88+
#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \
89+
(assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
90+
#else
91+
#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
92+
#endif
93+
7794
#ifdef __cplusplus
7895
}
7996
#endif

Python/marshal.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ w_more(int c, WFILE *p)
6969
p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
7070
p->end =
7171
PyString_AS_STRING((PyStringObject *)p->str) + newsize;
72-
*p->ptr++ = (char) c;
72+
*p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
7373
}
7474
}
7575

0 commit comments

Comments
 (0)