@@ -187,45 +187,74 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
187187 WARN ("Truncation of value to int" );
188188 break ;
189189 }
190- case T_UINT :{
191- unsigned long ulong_val = PyLong_AsUnsignedLong (v );
192- if ((ulong_val == (unsigned long )-1 ) && PyErr_Occurred ()) {
193- /* XXX: For compatibility, accept negative int values
194- as well. */
195- PyErr_Clear ();
196- ulong_val = PyLong_AsLong (v );
197- if ((ulong_val == (unsigned long )-1 ) &&
198- PyErr_Occurred ())
190+ case T_UINT : {
191+ /* XXX: For compatibility, accept negative int values
192+ as well. */
193+ int overflow ;
194+ long long_val = PyLong_AsLongAndOverflow (v , & overflow );
195+ if (long_val == -1 && PyErr_Occurred ()) {
196+ return -1 ;
197+ }
198+ if (overflow < 0 ) {
199+ PyErr_SetString (PyExc_OverflowError ,
200+ "Python int too large to convert to C long" );
201+ return -1 ;
202+ }
203+ else if (!overflow ) {
204+ * (unsigned int * )addr = (unsigned int )(unsigned long )long_val ;
205+ if (long_val < 0 ) {
206+ WARN ("Writing negative value into unsigned field" );
207+ }
208+ else if ((unsigned long )long_val > UINT_MAX ) {
209+ WARN ("Truncation of value to unsigned short" );
210+ }
211+ }
212+ else {
213+ unsigned long ulong_val = PyLong_AsUnsignedLong (v );
214+ if (ulong_val == (unsigned long )-1 && PyErr_Occurred ()) {
199215 return -1 ;
200- * (unsigned int * )addr = (unsigned int )ulong_val ;
201- WARN ("Writing negative value into unsigned field" );
202- } else
203- * (unsigned int * )addr = (unsigned int )ulong_val ;
204- if (ulong_val > UINT_MAX )
205- WARN ("Truncation of value to unsigned int" );
206- break ;
216+ }
217+ * (unsigned int * )addr = (unsigned int )ulong_val ;
218+ if (ulong_val > UINT_MAX ) {
219+ WARN ("Truncation of value to unsigned int" );
220+ }
207221 }
222+ break ;
223+ }
208224 case T_LONG :{
209225 * (long * )addr = PyLong_AsLong (v );
210226 if ((* (long * )addr == -1 ) && PyErr_Occurred ())
211227 return -1 ;
212228 break ;
213229 }
214- case T_ULONG :{
215- * (unsigned long * )addr = PyLong_AsUnsignedLong (v );
216- if ((* (unsigned long * )addr == (unsigned long )-1 )
217- && PyErr_Occurred ()) {
218- /* XXX: For compatibility, accept negative int values
219- as well. */
220- PyErr_Clear ();
221- * (unsigned long * )addr = PyLong_AsLong (v );
222- if ((* (unsigned long * )addr == (unsigned long )-1 )
223- && PyErr_Occurred ())
230+ case T_ULONG : {
231+ /* XXX: For compatibility, accept negative int values
232+ as well. */
233+ int overflow ;
234+ long long_val = PyLong_AsLongAndOverflow (v , & overflow );
235+ if (long_val == -1 && PyErr_Occurred ()) {
236+ return -1 ;
237+ }
238+ if (overflow < 0 ) {
239+ PyErr_SetString (PyExc_OverflowError ,
240+ "Python int too large to convert to C long" );
241+ return -1 ;
242+ }
243+ else if (!overflow ) {
244+ * (unsigned long * )addr = (unsigned long )long_val ;
245+ if (long_val < 0 ) {
246+ WARN ("Writing negative value into unsigned field" );
247+ }
248+ }
249+ else {
250+ unsigned long ulong_val = PyLong_AsUnsignedLong (v );
251+ if (ulong_val == (unsigned long )-1 && PyErr_Occurred ()) {
224252 return -1 ;
225- WARN ("Writing negative value into unsigned field" );
253+ }
254+ * (unsigned long * )addr = ulong_val ;
226255 }
227256 break ;
228- }
257+ }
229258 case T_PYSSIZET :{
230259 * (Py_ssize_t * )addr = PyLong_AsSsize_t (v );
231260 if ((* (Py_ssize_t * )addr == (Py_ssize_t )- 1 )
0 commit comments