@@ -197,45 +197,74 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
197
197
WARN ("Truncation of value to int" );
198
198
break ;
199
199
}
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 ()) {
209
225
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
+ }
217
231
}
232
+ break ;
233
+ }
218
234
case T_LONG :{
219
235
* (long * )addr = PyLong_AsLong (v );
220
236
if ((* (long * )addr == -1 ) && PyErr_Occurred ())
221
237
return -1 ;
222
238
break ;
223
239
}
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 ()) {
234
262
return -1 ;
235
- WARN ("Writing negative value into unsigned field" );
263
+ }
264
+ * (unsigned long * )addr = ulong_val ;
236
265
}
237
266
break ;
238
- }
267
+ }
239
268
case T_PYSSIZET :{
240
269
* (Py_ssize_t * )addr = PyLong_AsSsize_t (v );
241
270
if ((* (Py_ssize_t * )addr == (Py_ssize_t )- 1 )
0 commit comments