Commit: 2dfc954c4a552f80f8e944c3b6a1a7b6995427a2
Author: Campbell Barton
Date:   Sun Jul 31 16:52:44 2016 +1000
Branches: master
https://developer.blender.org/rB2dfc954c4a552f80f8e944c3b6a1a7b6995427a2

PyAPI: Add PyC_UnicodeAsByteAndSize

Read the string length from Python directly when assigning id-properties

===================================================================

M       source/blender/blenkernel/intern/idprop.c
M       source/blender/python/generic/idprop_py_api.c
M       source/blender/python/generic/py_capi_utils.c
M       source/blender/python/generic/py_capi_utils.h

===================================================================

diff --git a/source/blender/blenkernel/intern/idprop.c 
b/source/blender/blenkernel/intern/idprop.c
index 86d010f..b2641b1 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -940,17 +940,18 @@ IDProperty *IDP_New(const char type, const 
IDPropertyTemplate *val, const char *
                                prop->subtype = IDP_STRING_SUB_BYTE;
                        }
                        else {
-                               if (st == NULL) {
+                               if (st == NULL || val->string.len <= 1) {
                                        prop->data.pointer = 
MEM_mallocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
                                        *IDP_String(prop) = '\0';
                                        prop->totallen = 
DEFAULT_ALLOC_FOR_NULL_STRINGS;
                                        prop->len = 1; /*NULL string, has len 
of 1 to account for null byte.*/
                                }
                                else {
-                                       int stlen = (int)strlen(st) + 1;
-                                       prop->data.pointer = 
MEM_mallocN((size_t)stlen, "id property string 3");
-                                       prop->len = prop->totallen = stlen;
-                                       memcpy(prop->data.pointer, st, 
(size_t)stlen);
+                                       BLI_assert((int)val->string.len <= 
(int)strlen(st) + 1);
+                                       prop->data.pointer = 
MEM_mallocN((size_t)val->string.len, "id property string 3");
+                                       memcpy(prop->data.pointer, st, 
(size_t)val->string.len - 1);
+                                       IDP_String(prop)[val->string.len - 1] = 
'\0';
+                                       prop->len = prop->totallen = 
val->string.len;
                                }
                                prop->subtype = IDP_STRING_SUB_UTF8;
                        }
diff --git a/source/blender/python/generic/idprop_py_api.c 
b/source/blender/python/generic/idprop_py_api.c
index fe4a63e..c978ae5 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -378,8 +378,10 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject 
*name_obj, IDProperty *group,
        }
        else if (PyUnicode_Check(ob)) {
 #ifdef USE_STRING_COERCE
+               Py_ssize_t value_size;
                PyObject *value_coerce = NULL;
-               val.string.str = PyC_UnicodeAsByte(ob, &value_coerce);
+               val.string.str = PyC_UnicodeAsByteAndSize(ob, &value_size, 
&value_coerce);
+               val.string.len = (int)value_size + 1;
                val.string.subtype = IDP_STRING_SUB_UTF8;
                prop = IDP_New(IDP_STRING, &val, name);
                Py_XDECREF(value_coerce);
diff --git a/source/blender/python/generic/py_capi_utils.c 
b/source/blender/python/generic/py_capi_utils.c
index 72dec55..7b2d58a 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -540,6 +540,35 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
 }
 
 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
+const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, 
PyObject **coerce)
+{
+       const char *result;
+
+       result = _PyUnicode_AsStringAndSize(py_str, size);
+
+       if (result) {
+               /* 99% of the time this is enough but we better support non 
unicode
+                * chars since blender doesnt limit this */
+               return result;
+       }
+       else {
+               PyErr_Clear();
+
+               if (PyBytes_Check(py_str)) {
+                       *size = PyBytes_GET_SIZE(py_str);
+                       return PyBytes_AS_STRING(py_str);
+               }
+               else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+                       *size = PyBytes_GET_SIZE(*coerce);
+                       return PyBytes_AS_STRING(*coerce);
+               }
+               else {
+                       /* leave error raised from EncodeFS */
+                       return NULL;
+               }
+       }
+}
+
 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
 {
        const char *result;
diff --git a/source/blender/python/generic/py_capi_utils.h 
b/source/blender/python/generic/py_capi_utils.h
index a06a717..04cfc88 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -53,6 +53,7 @@ void            PyC_List_Fill(PyObject *list, PyObject 
*value);
 PyObject *      PyC_UnicodeFromByte(const char *str);
 PyObject *      PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size);
 const char *    PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* 
coerce must be NULL */
+const char *    PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, 
PyObject **coerce);
 
 /* name namespace function for bpy & bge */
 PyObject *             PyC_DefaultNameSpace(const char *filename);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to