fix [#25776] Crash when operator's bl_idname has more than one dot
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -634,7 +635,9 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, i
|
||||
but= uiDefIconButO(block, BUT, ot->idname, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
|
||||
else
|
||||
but= uiDefButO(block, BUT, ot->idname, context, name, 0, 0, w, UI_UNIT_Y, NULL);
|
||||
|
||||
|
||||
assert(but->optype != NULL);
|
||||
|
||||
/* text alignment for toolbar buttons */
|
||||
if((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon)
|
||||
but->flag |= UI_TEXT_LEFT;
|
||||
|
||||
@@ -847,34 +847,56 @@ static StructRNA *rna_Operator_register(bContext *C, ReportList *reports, void *
|
||||
|
||||
{ /* convert foo.bar to FOO_OT_bar
|
||||
* allocate the description and the idname in 1 go */
|
||||
int idlen = strlen(_operator_idname) + 4;
|
||||
int namelen = strlen(_operator_name) + 1;
|
||||
int desclen = strlen(_operator_descr) + 1;
|
||||
char *ch, *ch_arr;
|
||||
ch_arr= ch= MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname"); /* 2 terminators and 3 to convert a.b -> A_OT_b */
|
||||
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
|
||||
dummyot.idname= ch;
|
||||
ch += idlen;
|
||||
strcpy(ch, _operator_name);
|
||||
dummyot.name = ch;
|
||||
ch += namelen;
|
||||
strcpy(ch, _operator_descr);
|
||||
dummyot.description = ch;
|
||||
|
||||
/* inconveniently long name sanity check */
|
||||
{
|
||||
char *ch= _operator_idname;
|
||||
int i;
|
||||
int dot= 0;
|
||||
for(i=0; *ch; i++) {
|
||||
if((*ch >= 'a' && *ch <= 'z') || (*ch >= '0' && *ch <= '9') || *ch == '_') {
|
||||
/* pass */
|
||||
}
|
||||
else if(*ch == '.') {
|
||||
dot++;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', at position %d", identifier, _operator_idname, i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch++;
|
||||
}
|
||||
|
||||
if(i > ((int)sizeof(dummyop.idname)) - 3) {
|
||||
BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', is too long, maximum length is %d.", identifier, _operator_idname, (int)sizeof(dummyop.idname) - 3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(dot != 1) {
|
||||
BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", identifier, _operator_idname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* end sanity check */
|
||||
|
||||
{
|
||||
int idlen = strlen(_operator_idname) + 4;
|
||||
int namelen = strlen(_operator_name) + 1;
|
||||
int desclen = strlen(_operator_descr) + 1;
|
||||
char *ch, *ch_arr;
|
||||
ch_arr= ch= MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname"); /* 2 terminators and 3 to convert a.b -> A_OT_b */
|
||||
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
|
||||
dummyot.idname= ch;
|
||||
ch += idlen;
|
||||
strcpy(ch, _operator_name);
|
||||
dummyot.name = ch;
|
||||
ch += namelen;
|
||||
strcpy(ch, _operator_descr);
|
||||
dummyot.description = ch;
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen(identifier) >= sizeof(dummyop.idname)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s' is too long, maximum length is %d.", identifier, (int)sizeof(dummyop.idname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* sanity check on name
|
||||
* foo.bar */
|
||||
// {
|
||||
// char *ch;
|
||||
// for(ch=identifier)
|
||||
|
||||
// }
|
||||
|
||||
/* check if we have registered this operator type before, and remove it */
|
||||
{
|
||||
wmOperatorType *ot= WM_operatortype_find(dummyot.idname, TRUE);
|
||||
|
||||
@@ -1092,19 +1092,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
|
||||
}
|
||||
else {
|
||||
if(data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
|
||||
else {
|
||||
if(RNA_property_flag(prop) & PROP_NEVER_CLAMP) {
|
||||
int param_size_max= RNA_property_string_maxlength(prop);
|
||||
if(param_size > param_size_max) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s only supports a string of length %d, found %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), param_size, param_size_max);
|
||||
return -1;
|
||||
}
|
||||
#ifdef USE_STRING_COERCE
|
||||
Py_XDECREF(value_coerce);
|
||||
#endif // USE_STRING_COERCE
|
||||
}
|
||||
RNA_property_string_set(ptr, prop, param);
|
||||
}
|
||||
else RNA_property_string_set(ptr, prop, param);
|
||||
}
|
||||
#ifdef USE_STRING_COERCE
|
||||
Py_XDECREF(value_coerce);
|
||||
|
||||
Reference in New Issue
Block a user