@@ -197,45 +197,74 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
197197 WARN ("Truncation of value to int" );
198198 break ;
199199 }
200- case T_UINT :{
201- unsigned long ulong_val = PyLong_AsUnsignedLong (v );
202- if ((ulong_val == (unsigned long )-1 ) && PyErr_Occurred ()) {
203- /* XXX: For compatibility, accept negative int values
204- as well. */
205- PyErr_Clear ();
206- ulong_val = PyLong_AsLong (v );
207- if ((ulong_val == (unsigned long )-1 ) &&
208- PyErr_Occurred ())
200+ case T_UINT : {
201+ /* XXX: For compatibility, accept negative int values
202+ as well. */
203+ int overflow ;
204+ long long_val = PyLong_AsLongAndOverflow (v , & overflow );
205+ if (long_val == -1 && PyErr_Occurred ()) {
206+ return -1 ;
207+ }
208+ if (overflow < 0 ) {
209+ PyErr_SetString (PyExc_OverflowError ,
210+ "Python int too large to convert to C long" );
211+ return -1 ;
212+ }
213+ else if (!overflow ) {
214+ * (unsigned int * )addr = (unsigned int )(unsigned long )long_val ;
215+ if (long_val < 0 ) {
216+ WARN ("Writing negative value into unsigned field" );
217+ }
218+ else if ((unsigned long )long_val > UINT_MAX ) {
219+ WARN ("Truncation of value to unsigned short" );
220+ }
221+ }
222+ else {
223+ unsigned long ulong_val = PyLong_AsUnsignedLong (v );
224+ if (ulong_val == (unsigned long )-1 && PyErr_Occurred ()) {
209225 return -1 ;
210- * (unsigned int * )addr = (unsigned int )ulong_val ;
211- WARN ("Writing negative value into unsigned field" );
212- } else
213- * (unsigned int * )addr = (unsigned int )ulong_val ;
214- if (ulong_val > UINT_MAX )
215- WARN ("Truncation of value to unsigned int" );
216- break ;
226+ }
227+ * (unsigned int * )addr = (unsigned int )ulong_val ;
228+ if (ulong_val > UINT_MAX ) {
229+ WARN ("Truncation of value to unsigned int" );
230+ }
217231 }
232+ break ;
233+ }
218234 case T_LONG :{
219235 * (long * )addr = PyLong_AsLong (v );
220236 if ((* (long * )addr == -1 ) && PyErr_Occurred ())
221237 return -1 ;
222238 break ;
223239 }
224- case T_ULONG :{
225- * (unsigned long * )addr = PyLong_AsUnsignedLong (v );
226- if ((* (unsigned long * )addr == (unsigned long )-1 )
227- && PyErr_Occurred ()) {
228- /* XXX: For compatibility, accept negative int values
229- as well. */
230- PyErr_Clear ();
231- * (unsigned long * )addr = PyLong_AsLong (v );
232- if ((* (unsigned long * )addr == (unsigned long )-1 )
233- && PyErr_Occurred ())
240+ case T_ULONG : {
241+ /* XXX: For compatibility, accept negative int values
242+ as well. */
243+ int overflow ;
244+ long long_val = PyLong_AsLongAndOverflow (v , & overflow );
245+ if (long_val == -1 && PyErr_Occurred ()) {
246+ return -1 ;
247+ }
248+ if (overflow < 0 ) {
249+ PyErr_SetString (PyExc_OverflowError ,
250+ "Python int too large to convert to C long" );
251+ return -1 ;
252+ }
253+ else if (!overflow ) {
254+ * (unsigned long * )addr = (unsigned long )long_val ;
255+ if (long_val < 0 ) {
256+ WARN ("Writing negative value into unsigned field" );
257+ }
258+ }
259+ else {
260+ unsigned long ulong_val = PyLong_AsUnsignedLong (v );
261+ if (ulong_val == (unsigned long )-1 && PyErr_Occurred ()) {
234262 return -1 ;
235- WARN ("Writing negative value into unsigned field" );
263+ }
264+ * (unsigned long * )addr = ulong_val ;
236265 }
237266 break ;
238- }
267+ }
239268 case T_PYSSIZET :{
240269 * (Py_ssize_t * )addr = PyLong_AsSsize_t (v );
241270 if ((* (Py_ssize_t * )addr == (Py_ssize_t )- 1 )
0 commit comments