fix [#25776] Crash when operator's bl_idname has more than one dot
authorCampbell Barton <ideasman42@gmail.com>
Mon, 24 Jan 2011 05:15:14 +0000 (05:15 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 24 Jan 2011 05:15:14 +0000 (05:15 +0000)
source/blender/editors/interface/interface_layout.c
source/blender/makesrna/intern/rna_wm.c
source/blender/python/intern/bpy_rna.c

index f6fc5364b813d657391f636cf43653b9f8044985..18bee084f40ab09f0e3f9145a7a2a6a54a82aade 100644 (file)
@@ -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;
index 6ef173113fd6ccdadccb9ba1439cc7cb70abcec5..c432123d6ba576ef0527eb8bc74f9dba96a02584 100644 (file)
@@ -847,33 +847,55 @@ 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;
-       }
 
-       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;
-       }
+               /* 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;
+                               }
 
-       /* sanity check on name
-        * foo.bar */
-//     {
-//             char *ch;
-//             for(ch=identifier)
+                               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;
+               }
+       }
 
        /* check if we have registered this operator type before, and remove it */
        {
index e75d898d3aa151258369c1e076d83178b6061acb..f789ed922e243aa777c37ee3d9237f4f0ac3a6e0 100644 (file)
@@ -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);