diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-03 05:13:51 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-03 05:13:51 +0400 |
commit | 854fd940165736db01eeff05719f1a60a6a89a8b (patch) | |
tree | f3269fc7c96cf8f8b685ec9fde379504609a6988 /source/gameengine/Expressions | |
parent | d92bd6bb0421ff98b209aba3aac34edfd1a08ab3 (diff) |
bge py api: raise an overflow exception when assigning a float to a bge object which is out of the float range.
also avoid raising exceptions by ConvertPythonToValue when they will be ignored.
Diffstat (limited to 'source/gameengine/Expressions')
-rw-r--r-- | source/gameengine/Expressions/ListValue.cpp | 8 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.cpp | 31 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.h | 2 |
3 files changed, 29 insertions, 12 deletions
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index abab40cbe67..c40394eceb1 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -425,7 +425,7 @@ static PyObject *listvalue_buffer_concat(PyObject *self, PyObject *other) for (i=0;i<numitems;i++) { - listitemval = listval->ConvertPythonToValue(PyList_GetItem(other,i), "cList + pyList: CListValue, "); + listitemval = listval->ConvertPythonToValue(PyList_GetItem(other,i), true, "cList + pyList: CListValue, "); if (listitemval) { listval_new->SetValue(i+numitems_orig, listitemval); @@ -570,7 +570,7 @@ PyAttributeDef CListValue::Attributes[] = { PyObject *CListValue::Pyappend(PyObject *value) { - CValue* objval = ConvertPythonToValue(value, "CList.append(i): CValueList, "); + CValue *objval = ConvertPythonToValue(value, true, "CList.append(i): CValueList, "); if (!objval) /* ConvertPythonToValue sets the error */ return NULL; @@ -595,7 +595,7 @@ PyObject *CListValue::Pyindex(PyObject *value) { PyObject *result = NULL; - CValue* checkobj = ConvertPythonToValue(value, "val = cList[i]: CValueList, "); + CValue *checkobj = ConvertPythonToValue(value, true, "val = cList[i]: CValueList, "); if (checkobj==NULL) return NULL; /* ConvertPythonToValue sets the error */ @@ -624,7 +624,7 @@ PyObject *CListValue::Pycount(PyObject *value) { int numfound = 0; - CValue* checkobj = ConvertPythonToValue(value, ""); /* error ignored */ + CValue *checkobj = ConvertPythonToValue(value, false, ""); /* error ignored */ if (checkobj==NULL) { /* in this case just return that there are no items in the list */ PyErr_Clear(); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 383e83dcd89..e5c4001de4c 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -537,10 +537,17 @@ PyObject *CValue::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrde return PyUnicode_From_STR_String(self->GetName()); } -CValue* CValue::ConvertPythonToValue(PyObject *pyobj, const char *error_prefix) +/** + * There are 2 reasons this could return NULL + * - unsupported type. + * - error converting (overflow). + * + * \param do_type_exception Use to skip raising an exception for unknown types. + */ +CValue *CValue::ConvertPythonToValue(PyObject *pyobj, const bool do_type_exception, const char *error_prefix) { - CValue* vallie = NULL; + CValue *vallie; /* refcounting is broking here! - this crashes anyway, just store a python list for KX_GameObject */ #if 0 if (PyList_Check(pyobj)) @@ -581,7 +588,14 @@ CValue* CValue::ConvertPythonToValue(PyObject *pyobj, const char *error_prefix) } else if (PyFloat_Check(pyobj)) { - vallie = new CFloatValue( (float)PyFloat_AsDouble(pyobj) ); + const double tval = PyFloat_AsDouble(pyobj); + if (tval > (double)FLT_MAX || tval < (double)-FLT_MAX) { + PyErr_Format(PyExc_OverflowError, "%soverflow converting from float, out of internal range", error_prefix); + vallie = NULL; + } + else { + vallie = new CFloatValue((float)tval); + } } else if (PyLong_Check(pyobj)) { @@ -594,10 +608,13 @@ CValue* CValue::ConvertPythonToValue(PyObject *pyobj, const char *error_prefix) if (PyObject_TypeCheck(pyobj, &CValue::Type)) /* Note, don't let these get assigned to GameObject props, must check elsewhere */ { vallie = (static_cast<CValue *>(BGE_PROXY_REF(pyobj)))->AddRef(); - } else - { - /* return an error value from the caller */ - PyErr_Format(PyExc_TypeError, "%scould convert python value to a game engine property", error_prefix); + } + else { + if (do_type_exception) { + /* return an error value from the caller */ + PyErr_Format(PyExc_TypeError, "%scould convert python value to a game engine property", error_prefix); + } + vallie = NULL; } return vallie; diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index e9bb6b1ba3c..db7d69a638f 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -220,7 +220,7 @@ public: return NULL; } - virtual CValue *ConvertPythonToValue(PyObject *pyobj, const char *error_prefix); + virtual CValue *ConvertPythonToValue(PyObject *pyobj, const bool do_type_exception, const char *error_prefix); static PyObject *pyattr_get_name(void *self, const KX_PYATTRIBUTE_DEF *attrdef); |