diff options
| author | Antoine Pitrou <solipsis@pitrou.net> | 2012-09-20 20:56:47 +0200 |
|---|---|---|
| committer | Antoine Pitrou <solipsis@pitrou.net> | 2012-09-20 20:56:47 +0200 |
| commit | ca8aa4acf6755dd012706e1e38fb737ae83ab5c6 (patch) | |
| tree | 310b20a536a99dd80657e2d22e07bb1466d0a895 /Objects | |
| parent | 1c47222a256f2977dcbb36c05dce7a5ae8e6ae06 (diff) | |
| download | cpython-git-ca8aa4acf6755dd012706e1e38fb737ae83ab5c6.tar.gz | |
Issue #15144: Fix possible integer overflow when handling pointers as integer values, by using Py_uintptr_t instead of size_t.
Patch by Serhiy Storchaka.
Diffstat (limited to 'Objects')
| -rw-r--r-- | Objects/obmalloc.c | 7 | ||||
| -rw-r--r-- | Objects/stringlib/codecs.h | 14 | ||||
| -rw-r--r-- | Objects/stringlib/fastsearch.h | 3 | ||||
| -rw-r--r-- | Objects/stringlib/find_max_char.h | 11 | ||||
| -rw-r--r-- | Objects/unicodeobject.c | 15 |
5 files changed, 18 insertions, 32 deletions
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 925482156d..6225ebbbf1 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -138,7 +138,6 @@ static int running_on_valgrind = -1; */ #define ALIGNMENT 8 /* must be 2^N */ #define ALIGNMENT_SHIFT 3 -#define ALIGNMENT_MASK (ALIGNMENT - 1) /* Return the number of bytes in size class I, as a uint. */ #define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) @@ -314,14 +313,12 @@ struct arena_object { struct arena_object* prevarena; }; -#undef ROUNDUP -#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK) -#define POOL_OVERHEAD ROUNDUP(sizeof(struct pool_header)) +#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) #define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ /* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ -#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK)) +#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) /* Return total number of blocks in pool of size index I, as a uint. */ #define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 7d55f49a00..2a01089c0f 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -2,9 +2,6 @@ #if STRINGLIB_IS_UNICODE -/* Mask to check or force alignment of a pointer to C 'long' boundaries */ -#define LONG_PTR_MASK (size_t) (SIZEOF_LONG - 1) - /* Mask to quickly check whether a C 'long' contains a non-ASCII, UTF8-encoded char. */ #if (SIZEOF_LONG == 8) @@ -25,7 +22,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, { Py_UCS4 ch; const char *s = *inptr; - const char *aligned_end = (const char *) ((size_t) end & ~LONG_PTR_MASK); + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); STRINGLIB_CHAR *p = dest + *outpos; while (s < end) { @@ -39,7 +36,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, First, check if we can do an aligned read, as most CPUs have a penalty for unaligned reads. */ - if (!((size_t) s & LONG_PTR_MASK)) { + if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) { /* Help register allocation */ register const char *_s = s; register STRINGLIB_CHAR *_p = p; @@ -453,7 +450,7 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, { Py_UCS4 ch; const unsigned char *aligned_end = - (const unsigned char *) ((size_t) e & ~LONG_PTR_MASK); + (const unsigned char *) _Py_ALIGN_DOWN(e, SIZEOF_LONG); const unsigned char *q = *inptr; STRINGLIB_CHAR *p = dest + *outpos; /* Offsets from q for retrieving byte pairs in the right order. */ @@ -468,7 +465,7 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, Py_UCS4 ch2; /* First check for possible aligned read of a C 'long'. Unaligned reads are more expensive, better to defer to another iteration. */ - if (!((size_t) q & LONG_PTR_MASK)) { + if (_Py_IS_ALIGNED(q, SIZEOF_LONG)) { /* Fast path for runs of in-range non-surrogate chars. */ register const unsigned char *_q = q; while (_q < aligned_end) { @@ -565,7 +562,6 @@ IllegalSurrogate: #undef FAST_CHAR_MASK #undef STRIPPED_MASK #undef SWAB -#undef LONG_PTR_MASK Py_LOCAL_INLINE(void) @@ -588,7 +584,7 @@ STRINGLIB(utf16_encode)(unsigned short *out, _PyUnicode_CONVERT_BYTES(STRINGLIB_CHAR, unsigned short, in, end, out); # endif } else { - const STRINGLIB_CHAR *unrolled_end = in + (len & ~ (Py_ssize_t) 3); + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); while (in < unrolled_end) { out[0] = SWAB2(in[0]); out[1] = SWAB2(in[1]); diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 5b8d5dbcdd..ecf885e7e1 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -43,8 +43,7 @@ STRINGLIB(fastsearch_memchr_1char)(const STRINGLIB_CHAR* s, Py_ssize_t n, #define DO_MEMCHR(memchr, s, needle, nchars) do { \ candidate = memchr((const void *) (s), (needle), (nchars) * sizeof(STRINGLIB_CHAR)); \ - found = (const STRINGLIB_CHAR *) \ - ((Py_ssize_t) candidate & (~ ((Py_ssize_t) sizeof(STRINGLIB_CHAR) - 1))); \ + found = (const STRINGLIB_CHAR *) _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); \ } while (0) if (mode == FAST_SEARCH) { diff --git a/Objects/stringlib/find_max_char.h b/Objects/stringlib/find_max_char.h index 9e344a0de9..06559c8a9f 100644 --- a/Objects/stringlib/find_max_char.h +++ b/Objects/stringlib/find_max_char.h @@ -2,9 +2,6 @@ #if STRINGLIB_IS_UNICODE -/* Mask to check or force alignment of a pointer to C 'long' boundaries */ -#define LONG_PTR_MASK (size_t) (SIZEOF_LONG - 1) - /* Mask to quickly check whether a C 'long' contains a non-ASCII, UTF8-encoded char. */ #if (SIZEOF_LONG == 8) @@ -21,10 +18,11 @@ Py_LOCAL_INLINE(Py_UCS4) STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) { const unsigned char *p = (const unsigned char *) begin; - const unsigned char *aligned_end = (const unsigned char *) ((size_t) end & ~LONG_PTR_MASK); + const unsigned char *aligned_end = + (const unsigned char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); while (p < end) { - if (!((size_t) p & LONG_PTR_MASK)) { + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { /* Help register allocation */ register const unsigned char *_p = p; while (_p < aligned_end) { @@ -43,7 +41,6 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) return 127; } -#undef LONG_PTR_MASK #undef ASCII_CHAR_MASK #else /* STRINGLIB_SIZEOF_CHAR == 1 */ @@ -72,7 +69,7 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) register Py_UCS4 mask; Py_ssize_t n = end - begin; const STRINGLIB_CHAR *p = begin; - const STRINGLIB_CHAR *unrolled_end = begin + (n & ~ (Py_ssize_t) 3); + const STRINGLIB_CHAR *unrolled_end = begin + _Py_SIZE_ROUND_DOWN(n, 4); Py_UCS4 max_char; max_char = MAX_CHAR_ASCII; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 61f743ebda..748508b278 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -159,7 +159,7 @@ extern "C" { const from_type *_end = (end); \ Py_ssize_t n = (_end) - (_iter); \ const from_type *_unrolled_end = \ - _iter + (n & ~ (Py_ssize_t) 3); \ + _iter + _Py_SIZE_ROUND_DOWN(n, 4); \ while (_iter < (_unrolled_end)) { \ _to[0] = (to_type) _iter[0]; \ _to[1] = (to_type) _iter[1]; \ @@ -4635,9 +4635,6 @@ PyUnicode_DecodeUTF8(const char *s, #include "stringlib/codecs.h" #include "stringlib/undef.h" -/* Mask to check or force alignment of a pointer to C 'long' boundaries */ -#define LONG_PTR_MASK (size_t) (SIZEOF_LONG - 1) - /* Mask to quickly check whether a C 'long' contains a non-ASCII, UTF8-encoded char. */ #if (SIZEOF_LONG == 8) @@ -4652,11 +4649,11 @@ static Py_ssize_t ascii_decode(const char *start, const char *end, Py_UCS1 *dest) { const char *p = start; - const char *aligned_end = (const char *) ((size_t) end & ~LONG_PTR_MASK); + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); #if SIZEOF_LONG <= SIZEOF_VOID_P - assert(!((size_t) dest & LONG_PTR_MASK)); - if (!((size_t) p & LONG_PTR_MASK)) { + assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { /* Fast path, see in STRINGLIB(utf8_decode) for an explanation. */ /* Help register allocation */ @@ -4682,7 +4679,7 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) while (p < end) { /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h for an explanation. */ - if (!((size_t) p & LONG_PTR_MASK)) { + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { /* Help register allocation */ register const char *_p = p; while (_p < aligned_end) { @@ -5390,7 +5387,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, return NULL; /* output buffer is 2-bytes aligned */ - assert(((Py_uintptr_t)PyBytes_AS_STRING(v) & 1) == 0); + assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 2)); out = (unsigned short *)PyBytes_AS_STRING(v); if (byteorder == 0) *out++ = 0xFEFF; |
