diff options
Diffstat (limited to 'Python/structmember.c')
| -rw-r--r-- | Python/structmember.c | 128 | 
1 files changed, 75 insertions, 53 deletions
diff --git a/Python/structmember.c b/Python/structmember.c index 54eb055..03934c0 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -62,29 +62,28 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)  	addr += l->offset;  	switch (l->type) {  	case T_BYTE: -		v = PyInt_FromLong( -			(long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80)); +		v = PyInt_FromLong(*(char*)addr);  		break;  	case T_UBYTE: -		v = PyInt_FromLong((long) *(char*)addr & 0xff); +		v = PyLong_FromUnsignedLong(*(unsigned char*)addr);  		break;  	case T_SHORT: -		v = PyInt_FromLong((long) *(short*)addr); +		v = PyInt_FromLong(*(short*)addr);  		break;  	case T_USHORT: -		v = PyInt_FromLong((long) *(unsigned short*)addr); +		v = PyLong_FromUnsignedLong(*(unsigned short*)addr);  		break;  	case T_INT: -		v = PyInt_FromLong((long) *(int*)addr); +		v = PyInt_FromLong(*(int*)addr);  		break;  	case T_UINT: -		v = PyInt_FromLong((long) *(unsigned int*)addr); +		v = PyLong_FromUnsignedLong(*(unsigned int*)addr);  		break;  	case T_LONG:  		v = PyInt_FromLong(*(long*)addr);  		break;  	case T_ULONG: -		v = PyLong_FromDouble((double) *(unsigned long*)addr); +		v = PyLong_FromUnsignedLong(*(unsigned long*)addr);  		break;  	case T_FLOAT:  		v = PyFloat_FromDouble((double)*(float*)addr); @@ -175,68 +174,91 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)  	}  	addr += l->offset;  	switch (l->type) { -	case T_BYTE: -	case T_UBYTE: -		if (!PyInt_Check(v)) { -			PyErr_BadArgument(); +	case T_BYTE:{ +		long long_val; +		long_val = PyInt_AsLong(v); +		if ((long_val == -1) && PyErr_Occurred())  			return -1; -		} -		*(char*)addr = (char) PyInt_AsLong(v); +		*(char*)addr = (char)long_val;  		break; -	case T_SHORT: -	case T_USHORT: -		if (!PyInt_Check(v)) { -			PyErr_BadArgument(); -			return -1;  		} -		*(short*)addr = (short) PyInt_AsLong(v); +	case T_UBYTE:{ +		long long_val; +		long_val = PyInt_AsLong(v); +		if ((long_val == -1) && PyErr_Occurred()) +			return -1; +		*(unsigned char*)addr = (unsigned char)long_val;  		break; -	case T_UINT: -	case T_INT: -		if (!PyInt_Check(v)) { -			PyErr_BadArgument(); +		} +	case T_SHORT:{ +		long long_val; +		long_val = PyInt_AsLong(v); +		if ((long_val == -1) && PyErr_Occurred())  			return -1; +		*(short*)addr = (short)long_val; +		break;  		} -		*(int*)addr = (int) PyInt_AsLong(v); +	case T_USHORT:{ +		long long_val; +		long_val = PyInt_AsLong(v); +		if ((long_val == -1) && PyErr_Occurred()) +			return -1; +		*(unsigned short*)addr = (unsigned short)long_val;  		break; -	case T_LONG: -		if (!PyInt_Check(v)) { -			PyErr_BadArgument(); +		} +  	case T_INT:{ +		long long_val; +		long_val = PyInt_AsLong(v); +		if ((long_val == -1) && PyErr_Occurred())  			return -1; +		*(int *)addr = (int)long_val; +		break; +		} +	case T_UINT:{ +		unsigned long ulong_val; +		ulong_val = PyLong_AsUnsignedLong(v); +		if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) { +			/* XXX: For compatibility, accept negative int values +			   as well. */ +			PyErr_Clear(); +			ulong_val = PyLong_AsLong(v); +			if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) +				return -1;  		} -		*(long*)addr = PyInt_AsLong(v); +		*(unsigned int *)addr = (unsigned int)ulong_val;  		break; -	case T_ULONG: -		if (PyInt_Check(v)) -			*(long*)addr = PyInt_AsLong(v); -		else if (PyLong_Check(v)) -			*(long*)addr = PyLong_AsLong(v); -		else { -			PyErr_BadArgument(); +		} +	case T_LONG:{ +		*(long*)addr = PyLong_AsLong(v); +		if ((*(long*)addr == -1) && PyErr_Occurred())  			return -1; +		break; +		} +	case T_ULONG:{ +		*(unsigned long*)addr = PyLong_AsUnsignedLong(v); +		if ((*(unsigned long*)addr == (unsigned long)-1) +		    && PyErr_Occurred()) { +			/* XXX: For compatibility, accept negative int values +			   as well. */ +			PyErr_Clear(); +			*(unsigned long*)addr = PyLong_AsLong(v); +			if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred()) +				return -1;  		}  		break; -	case T_FLOAT: -		if (PyInt_Check(v)) -			*(float*)addr = -				(float) PyInt_AsLong(v); -		else if (PyFloat_Check(v)) -			*(float*)addr = -				(float) PyFloat_AsDouble(v); -		else { -			PyErr_BadArgument(); -			return -1;  		} +	case T_FLOAT:{ +		double double_val; +		double_val = PyFloat_AsDouble(v); +		if ((double_val == -1) && PyErr_Occurred()) +			return -1; +		*(float*)addr = (float)double_val;  		break; +		}  	case T_DOUBLE: -		if (PyInt_Check(v)) -			*(double*)addr = (double) PyInt_AsLong(v); -		else if (PyFloat_Check(v)) -			*(double*)addr = PyFloat_AsDouble(v); -		else { -			PyErr_BadArgument(); +		*(double*)addr = PyFloat_AsDouble(v); +		if ((*(double*)addr == -1) && PyErr_Occurred())  			return -1; -		}  		break;  	case T_OBJECT:  	case T_OBJECT_EX:  | 
