mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Proper overflow checking for numeric chars
This commit is contained in:
parent
342b9a8db8
commit
5913546229
@ -4929,7 +4929,9 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
expected_params += "long";
|
||||
only_pyobjects = false;
|
||||
|
||||
} else if (TypeManager::is_unsigned_short(type)) {
|
||||
} else if (TypeManager::is_unsigned_short(type) ||
|
||||
TypeManager::is_unsigned_char(type) || TypeManager::is_signed_char(type)) {
|
||||
|
||||
if (args_type == AT_single_arg) {
|
||||
type_check = "PyLongOrInt_Check(arg)";
|
||||
extra_convert
|
||||
@ -4945,12 +4947,25 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
// The "H" format code, unlike "h", does not do overflow checking, so
|
||||
// we have to do it ourselves (except in release builds).
|
||||
extra_convert
|
||||
<< "#ifndef NDEBUG\n"
|
||||
<< "if (" << param_name << " < 0 || " << param_name << " > USHRT_MAX) {\n";
|
||||
<< "#ifndef NDEBUG\n";
|
||||
|
||||
if (TypeManager::is_unsigned_short(type)) {
|
||||
extra_convert << "if (" << param_name << " < 0 || " << param_name << " > USHRT_MAX) {\n";
|
||||
error_raise_return(extra_convert, 2, return_flags, "OverflowError",
|
||||
"value %ld out of range for unsigned short integer",
|
||||
param_name);
|
||||
} else if (TypeManager::is_unsigned_char(type)) {
|
||||
extra_convert << "if (" << param_name << " < 0 || " << param_name << " > UCHAR_MAX) {\n";
|
||||
error_raise_return(extra_convert, 2, return_flags, "OverflowError",
|
||||
"value %ld out of range for unsigned byte",
|
||||
param_name);
|
||||
} else {
|
||||
extra_convert << "if (" << param_name << " < CHAR_MIN || " << param_name << " > CHAR_MAX) {\n";
|
||||
error_raise_return(extra_convert, 2, return_flags, "OverflowError",
|
||||
"value %ld out of range for signed byte",
|
||||
param_name);
|
||||
}
|
||||
|
||||
error_raise_return(extra_convert, 2, return_flags, "OverflowError",
|
||||
"value %ld out of range for unsigned short integer",
|
||||
param_name);
|
||||
extra_convert
|
||||
<< "}\n"
|
||||
<< "#endif\n";
|
||||
|
@ -638,6 +638,40 @@ is_unsigned_char(CPPType *type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_signed_char
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is signed char,
|
||||
// but not unsigned or 'plain' char.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_signed_char(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_signed_char(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_simple:
|
||||
{
|
||||
CPPSimpleType *simple_type = type->as_simple_type();
|
||||
|
||||
if (simple_type != (CPPSimpleType *)NULL) {
|
||||
return
|
||||
(simple_type->_type == CPPSimpleType::T_char) &&
|
||||
(simple_type->_flags & CPPSimpleType::F_signed) != 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CPPDeclaration::ST_typedef:
|
||||
return is_signed_char(type->as_typedef_type()->_type);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_char_pointer
|
||||
// Access: Public, Static
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
static bool is_pointable(CPPType *type);
|
||||
static bool is_char(CPPType *type);
|
||||
static bool is_unsigned_char(CPPType *type);
|
||||
static bool is_signed_char(CPPType *type);
|
||||
static bool is_char_pointer(CPPType *type);
|
||||
static bool is_const_char_pointer(CPPType *type);
|
||||
static bool is_unsigned_char_pointer(CPPType *type);
|
||||
|
Loading…
x
Reference in New Issue
Block a user