Fix: frozen mathutils Vector & Matrix types could be resized
It's important that frozen types are immutable, add a generic check that mathutils types can be resized and check the frozen flag. Also correct the exception types when Vector's cant be resized, using a ValueError instead of a TypeError as the type is correct.
This commit is contained in:
@@ -612,6 +612,24 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
|
||||
PyExc_TypeError, "%s is not frozen (mutable), call freeze first", Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
int _BaseMathObject_ResizeOkOrRaiseExc(BaseMathObject *self, const char *error_prefix)
|
||||
{
|
||||
if (UNLIKELY(self->flag & BASE_MATH_FLAG_IS_FROZEN)) {
|
||||
PyErr_Format(PyExc_ValueError, "%s: cannot resize frozen data", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
if (UNLIKELY(self->flag & BASE_MATH_FLAG_IS_WRAP)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError, "%s: cannot resize wrapped data - only Python vectors", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
if (UNLIKELY(self->cb_user)) {
|
||||
PyErr_Format(PyExc_TypeError, "%s: cannot resize a vector that has an owner", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #BaseMathObject generic functions for all mathutils types. */
|
||||
|
||||
char BaseMathObject_owner_doc[] = "The item this is wrapping or None (read-only).";
|
||||
|
||||
@@ -118,6 +118,9 @@ struct Mathutils_Callback {
|
||||
[[nodiscard]] int _BaseMathObject_WriteCallback(BaseMathObject *self);
|
||||
[[nodiscard]] int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
|
||||
[[nodiscard]] int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
|
||||
/** To implement #BaseMath_Prepare_ForResize. */
|
||||
[[nodiscard]] int _BaseMathObject_ResizeOkOrRaiseExc(BaseMathObject *self,
|
||||
const char *error_prefix);
|
||||
|
||||
void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self);
|
||||
void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
|
||||
@@ -154,6 +157,12 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
|
||||
(UNLIKELY(((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) == 0) ? \
|
||||
(_BaseMathObject_RaiseNotFrozenExc((BaseMathObject *)_self), -1) : \
|
||||
0)
|
||||
/**
|
||||
* Helper to de-duplicate checks for in-place resizing.
|
||||
* \return -1 and set an exception if the vector `_self` cannot be resized.
|
||||
*/
|
||||
#define BaseMathObject_Prepare_ForResize(_self, error_prefix) \
|
||||
_BaseMathObject_ResizeOkOrRaiseExc((BaseMathObject *)_self, error_prefix)
|
||||
|
||||
/* utility func */
|
||||
/**
|
||||
|
||||
@@ -1391,16 +1391,8 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
|
||||
float mat[4][4];
|
||||
int col;
|
||||
|
||||
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Matrix.resize_4x4(): "
|
||||
"cannot resize wrapped data - make a copy and resize that");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->cb_user) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Matrix.resize_4x4(): "
|
||||
"cannot resize owned data - make a copy and resize that");
|
||||
if (UNLIKELY(BaseMathObject_Prepare_ForResize(self, "Matrix.resize_4x4()") == -1)) {
|
||||
/* An exception has been raised. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -497,16 +497,8 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value)
|
||||
{
|
||||
int vec_num;
|
||||
|
||||
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize(): "
|
||||
"cannot resize wrapped data - only Python vectors");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->cb_user) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize(): "
|
||||
"cannot resize a vector that has an owner");
|
||||
if (UNLIKELY(BaseMathObject_Prepare_ForResize(self, "Vector.resize()") == -1)) {
|
||||
/* An exception has been raised. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -585,16 +577,8 @@ PyDoc_STRVAR(
|
||||
" Resize the vector to 2D (x, y).\n");
|
||||
static PyObject *Vector_resize_2d(VectorObject *self)
|
||||
{
|
||||
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_2d(): "
|
||||
"cannot resize wrapped data - only Python vectors");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->cb_user) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_2d(): "
|
||||
"cannot resize a vector that has an owner");
|
||||
if (UNLIKELY(BaseMathObject_Prepare_ForResize(self, "Vector.resize_2d()") == -1)) {
|
||||
/* An exception has been raised. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -618,16 +602,8 @@ PyDoc_STRVAR(
|
||||
" Resize the vector to 3D (x, y, z).\n");
|
||||
static PyObject *Vector_resize_3d(VectorObject *self)
|
||||
{
|
||||
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_3d(): "
|
||||
"cannot resize wrapped data - only Python vectors");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->cb_user) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_3d(): "
|
||||
"cannot resize a vector that has an owner");
|
||||
if (UNLIKELY(BaseMathObject_Prepare_ForResize(self, "Vector.resize_3d()") == -1)) {
|
||||
/* An exception has been raised. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -655,16 +631,8 @@ PyDoc_STRVAR(
|
||||
" Resize the vector to 4D (x, y, z, w).\n");
|
||||
static PyObject *Vector_resize_4d(VectorObject *self)
|
||||
{
|
||||
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_4d(): "
|
||||
"cannot resize wrapped data - only Python vectors");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->cb_user) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Vector.resize_4d(): "
|
||||
"cannot resize a vector that has an owner");
|
||||
if (UNLIKELY(BaseMathObject_Prepare_ForResize(self, "Vector.resize_4d()") == -1)) {
|
||||
/* An exception has been raised. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user