Index: Modules/_ctypes/callproc.c =================================================================== --- Modules/_ctypes/callproc.c (revision 54879) +++ Modules/_ctypes/callproc.c (working copy) @@ -498,21 +498,28 @@ if (PyInt_Check(obj)) { pa->ffi_type = &ffi_type_sint; - pa->value.i = PyInt_AS_LONG(obj); + pa->value.l = PyInt_AS_LONG(obj); +#if SIZEOF_INT < SIZEOF_LONG + if (pa->value.l != pa->value.i) { + PyErr_SetString(PyExc_OverflowError, + "int is too long to convert"); + return -1; + } +#endif return 0; } if (PyLong_Check(obj)) { pa->ffi_type = &ffi_type_sint; - pa->value.i = (long)PyLong_AsUnsignedLong(obj); - if (pa->value.i == -1 && PyErr_Occurred()) { - PyErr_Clear(); - pa->value.i = PyLong_AsLong(obj); - if (pa->value.i == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_OverflowError, - "long int too long to convert"); - return -1; - } + pa->value.l = PyLong_AsLong(obj); + if ((pa->value.l == -1 && PyErr_Occurred()) +#if SIZEOF_INT < SIZEOF_LONG + || pa->value.l != pa->value.i +#endif + ) { + PyErr_SetString(PyExc_OverflowError, + "long is too long to convert"); + return -1; } return 0; } Index: Modules/_ctypes/cfield.c =================================================================== --- Modules/_ctypes/cfield.c (revision 54879) +++ Modules/_ctypes/cfield.c (working copy) @@ -356,7 +356,7 @@ v->ob_type->tp_name); return -1; } - x = PyInt_AsUnsignedLongMask(v); + x = PyInt_AsLong(v); if (x == -1 && PyErr_Occurred()) return -1; *p = x; @@ -564,6 +564,11 @@ short x; if (get_long(value, &val) < 0) return NULL; + if (val != (short)val) { + PyErr_SetString(PyExc_OverflowError, + "value is too long for c short"); + return NULL; + } memcpy(&x, ptr, sizeof(x)); x = SET(x, (short)val, size); memcpy(ptr, &x, sizeof(x)); @@ -578,6 +583,11 @@ short field; if (get_long(value, &val) < 0) return NULL; + if (val != (short)val) { + PyErr_SetString(PyExc_OverflowError, + "value is too long for c short"); + return NULL; + } memcpy(&field, ptr, sizeof(field)); field = SWAP_2(field); field = SET(field, (short)val, size); @@ -660,6 +670,13 @@ int x; if (get_long(value, &val) < 0) return NULL; +#if SIZEOF_INT < SIZEOF_LONG + if (val != (int)val) { + PyErr_SetString(PyExc_OverflowError, + "value is too long for c int"); + return NULL; + } +#endif memcpy(&x, ptr, sizeof(x)); x = SET(x, (int)val, size); memcpy(ptr, &x, sizeof(x)); @@ -673,6 +690,13 @@ int field; if (get_long(value, &val) < 0) return NULL; +#if SIZEOF_INT < SIZEOF_LONG + if (val != (int)val) { + PyErr_SetString(PyExc_OverflowError, + "value is too long for c int"); + return NULL; + } +#endif memcpy(&field, ptr, sizeof(field)); field = SWAP_INT(field); field = SET(field, (int)val, size);