diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 29914eca576..a8cb2bd24f3 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -3635,12 +3635,12 @@ void BKE_image_set_filepath_from_tile_number(char *filepath, } if (tile_format == UDIM_TILE_FORMAT_UDIM) { - BLI_sprintf(filepath, pattern, tile_number); + BLI_snprintf(filepath, FILE_MAX, pattern, tile_number); } else if (tile_format == UDIM_TILE_FORMAT_UVTILE) { int u = ((tile_number - 1001) % 10); int v = ((tile_number - 1001) / 10); - BLI_sprintf(filepath, pattern, u + 1, v + 1); + BLI_snprintf(filepath, FILE_MAX, pattern, u + 1, v + 1); } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 3f9fa2a0baa..a6ad8629268 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3133,19 +3133,23 @@ void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene, ViewLayer *view_laye BKE_ptcache_bake(&baker); } -static void ptcache_dt_to_str(char *str, double dtime) +static void ptcache_dt_to_str(char *str, size_t str_maxncpy, double dtime) { if (dtime > 60.0) { if (dtime > 3600.0) { - BLI_sprintf( - str, "%ih %im %is", (int)(dtime / 3600), (int)(dtime / 60) % 60, ((int)dtime) % 60); + BLI_snprintf(str, + str_maxncpy, + "%ih %im %is", + (int)(dtime / 3600), + (int)(dtime / 60) % 60, + ((int)dtime) % 60); } else { - BLI_sprintf(str, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60); + BLI_snprintf(str, str_maxncpy, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60); } } else { - BLI_sprintf(str, "%is", ((int)dtime) % 60); + BLI_snprintf(str, str_maxncpy, "%is", ((int)dtime) % 60); } } @@ -3300,9 +3304,9 @@ void BKE_ptcache_bake(PTCacheBaker *baker) if (use_timer || fetd > 60.0) { use_timer = true; - ptcache_dt_to_str(cur, ctime - ptime); - ptcache_dt_to_str(run, ctime - stime); - ptcache_dt_to_str(etd, fetd); + ptcache_dt_to_str(cur, sizeof(cur), ctime - ptime); + ptcache_dt_to_str(run, sizeof(run), ctime - stime); + ptcache_dt_to_str(etd, sizeof(etd), fetd); printf("Baked for %s, current frame: %i/%i (%.3fs), ETC: %s\r", run, @@ -3325,7 +3329,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) if (use_timer) { /* start with newline because of \r above */ - ptcache_dt_to_str(run, PIL_check_seconds_timer() - stime); + ptcache_dt_to_str(run, sizeof(run), PIL_check_seconds_timer() - stime); printf("\nBake %s %s (%i frames simulated).\n", (cancel ? "canceled after" : "finished in"), run, diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 55dd81e0e46..2cd05ceab11 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -243,14 +243,6 @@ size_t BLI_vsnprintf_rlen(char *__restrict dst, char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2); -/** - * A wrapper around `::sprintf()` which does not generate security warnings. - * - * \note Use #BLI_snprintf for cases when the string size is known. - */ -int BLI_sprintf(char *__restrict str, const char *__restrict format, ...) ATTR_NONNULL(1, 2) - ATTR_PRINTF_FORMAT(2, 3); - /** * This roughly matches C and Python's string escaping with double quotes - `"`. * diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h index 8f1230fd1fc..686338941b9 100644 --- a/source/blender/blenlib/BLI_string_utils.h +++ b/source/blender/blenlib/BLI_string_utils.h @@ -118,6 +118,9 @@ bool BLI_uniquename(struct ListBase *list, /* Expand array functions. */ +size_t BLI_string_len_array(const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(); + /* Intentionally no comma after `_BLI_STRING_ARGS_0` to allow it to be empty. */ #define _BLI_STRING_ARGS_1 _BLI_STRING_ARGS_0 const char *a #define _BLI_STRING_ARGS_2 _BLI_STRING_ARGS_1, const char *b diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index bbf2140af57..7188e2966e2 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -244,17 +244,6 @@ char *BLI_sprintfN(const char *__restrict format, ...) return n; } -int BLI_sprintf(char *__restrict str, const char *__restrict format, ...) -{ - va_list arg; - - va_start(arg, format); - const int result = vsprintf(str, format, arg); - va_end(arg); - - return result; -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c index aca9ddf442e..0f72f8b81a1 100644 --- a/source/blender/blenlib/intern/string_utils.c +++ b/source/blender/blenlib/intern/string_utils.c @@ -357,6 +357,15 @@ bool BLI_uniquename(ListBase *list, name_maxncpy); } +size_t BLI_string_len_array(const char *strings[], uint strings_num) +{ + size_t total_len = 0; + for (uint i = 0; i < strings_num; i++) { + total_len += strlen(strings[i]); + } + return total_len; +} + /* ------------------------------------------------------------------------- */ /** \name Join Strings * @@ -411,11 +420,8 @@ size_t BLI_string_join_array_by_sep_char( char *BLI_string_join_arrayN(const char *strings[], uint strings_num) { - uint total_len = 1; - for (uint i = 0; i < strings_num; i++) { - total_len += strlen(strings[i]); - } - char *result = MEM_mallocN(sizeof(char) * total_len, __func__); + const uint result_size = BLI_string_len_array(strings, strings_num) + 1; + char *result = MEM_mallocN(sizeof(char) * result_size, __func__); char *c = result; for (uint i = 0; i < strings_num; i++) { const size_t string_len = strlen(strings[i]); @@ -424,20 +430,21 @@ char *BLI_string_join_arrayN(const char *strings[], uint strings_num) } /* Only needed when `strings_num == 0`. */ *c = '\0'; + BLI_assert(result + result_size == c + 1); return result; } char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_num) { - uint total_len = 0; + uint result_size = 0; for (uint i = 0; i < strings_num; i++) { - total_len += strlen(strings[i]) + 1; + result_size += strlen(strings[i]) + 1; } - if (total_len == 0) { - total_len = 1; + if (result_size == 0) { + result_size = 1; } - char *result = MEM_mallocN(sizeof(char) * total_len, __func__); + char *result = MEM_mallocN(sizeof(char) * result_size, __func__); char *c = result; if (strings_num != 0) { for (uint i = 0; i < strings_num; i++) { @@ -450,6 +457,7 @@ char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint s c--; } *c = '\0'; + BLI_assert(result + result_size == c + 1); return result; } @@ -458,15 +466,15 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, const char *strings[], uint strings_num) { - uint total_len = 0; + uint result_size = 0; for (uint i = 0; i < strings_num; i++) { - total_len += strlen(strings[i]) + 1; + result_size += strlen(strings[i]) + 1; } - if (total_len == 0) { - total_len = 1; + if (result_size == 0) { + result_size = 1; } - char *result = MEM_mallocN(sizeof(char) * total_len, __func__); + char *result = MEM_mallocN(sizeof(char) * result_size, __func__); char *c = result; if (strings_num != 0) { for (uint i = 0; i < strings_num; i++) { @@ -481,6 +489,7 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, c--; } *c = '\0'; + BLI_assert(result + result_size == c + 1); return result; } diff --git a/source/blender/blenlib/intern/uuid.cc b/source/blender/blenlib/intern/uuid.cc index 4a65d094b2c..bc0f854cfd1 100644 --- a/source/blender/blenlib/intern/uuid.cc +++ b/source/blender/blenlib/intern/uuid.cc @@ -88,19 +88,25 @@ bool BLI_uuid_equal(const bUUID uuid1, const bUUID uuid2) void BLI_uuid_format(char *buffer, const bUUID uuid) { - BLI_sprintf(buffer, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid.time_low, - uuid.time_mid, - uuid.time_hi_and_version, - uuid.clock_seq_hi_and_reserved, - uuid.clock_seq_low, - uuid.node[0], - uuid.node[1], - uuid.node[2], - uuid.node[3], - uuid.node[4], - uuid.node[5]); + const size_t buffer_len_unclamped = BLI_snprintf( + buffer, + UUID_STRING_LEN, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.time_low, + uuid.time_mid, + uuid.time_hi_and_version, + uuid.clock_seq_hi_and_reserved, + uuid.clock_seq_low, + uuid.node[0], + uuid.node[1], + uuid.node[2], + uuid.node[3], + uuid.node[4], + uuid.node[5]); + + /* Assert the string length is not clamped. */ + BLI_assert(buffer_len_unclamped == UUID_STRING_LEN - 1); + UNUSED_VARS_NDEBUG(buffer_len_unclamped); } bool BLI_uuid_parse_string(bUUID *uuid, const char *buffer) diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc index 64260f77b1b..2deba6b9620 100644 --- a/source/blender/editors/render/render_internal.cc +++ b/source/blender/editors/render/render_internal.cc @@ -15,6 +15,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" +#include "BLI_string_utils.h" #include "BLI_threads.h" #include "BLI_timecode.h" #include "BLI_utildefines.h" @@ -402,17 +403,25 @@ static void render_freejob(void *rjv) MEM_freeN(rj); } -/* str is IMA_MAX_RENDER_TEXT in size */ static void make_renderinfo_string(const RenderStats *rs, const Scene *scene, const bool v3d_override, const char *error, - char *str) + char ret[IMA_MAX_RENDER_TEXT]) { - char info_time_str[32]; /* used to be extern to header_info.c */ + const char *info_space = " "; + const char *info_sep = "| "; + struct { + char time_last[32]; + char time_elapsed[32]; + char frame[16]; + char statistics[64]; + } info_buffers; + uintptr_t mem_in_use, peak_memory; float megs_used_memory, megs_peak_memory; - char *spos = str; + const char *ret_array[32]; + int i = 0; mem_in_use = MEM_get_memory_in_use(); peak_memory = MEM_get_peak_memory(); @@ -422,65 +431,96 @@ static void make_renderinfo_string(const RenderStats *rs, /* local view */ if (rs->localview) { - spos += BLI_sprintf(spos, "%s | ", TIP_("3D Local View")); + ret_array[i++] = TIP_("3D Local View "); + ret_array[i++] = info_sep; } else if (v3d_override) { - spos += BLI_sprintf(spos, "%s | ", TIP_("3D View")); + ret_array[i++] = TIP_("3D View "); + ret_array[i++] = info_sep; } /* frame number */ - spos += BLI_sprintf(spos, TIP_("Frame:%d "), (scene->r.cfra)); + SNPRINTF(info_buffers.frame, "%d ", scene->r.cfra); + ret_array[i++] = TIP_("Frame:"); + ret_array[i++] = info_buffers.frame; - /* previous and elapsed time */ - BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), rs->lastframetime); + /* Previous and elapsed time. */ + const char *info_time = info_buffers.time_last; + BLI_timecode_string_from_time_simple( + info_buffers.time_last, sizeof(info_buffers.time_last), rs->lastframetime); + ret_array[i++] = info_sep; if (rs->infostr && rs->infostr[0]) { if (rs->lastframetime != 0.0) { - spos += BLI_sprintf(spos, TIP_("| Last:%s "), info_time_str); + ret_array[i++] = "Last:"; + ret_array[i++] = info_buffers.time_last; + ret_array[i++] = info_space; + } + + info_time = info_buffers.time_elapsed; + BLI_timecode_string_from_time_simple(info_buffers.time_elapsed, + sizeof(info_buffers.time_elapsed), + PIL_check_seconds_timer() - rs->starttime); + } + + ret_array[i++] = TIP_("Time:"); + ret_array[i++] = info_time; + ret_array[i++] = info_space; + + /* Statistics. */ + { + const char *info_statistics = nullptr; + if (rs->statstr) { + if (rs->statstr[0]) { + info_statistics = rs->statstr; + } } else { - spos += BLI_sprintf(spos, "| "); + if (rs->mem_peak == 0.0f) { + SNPRINTF(info_buffers.statistics, + TIP_("Mem:%.2fM (Peak %.2fM)"), + megs_used_memory, + megs_peak_memory); + } + else { + SNPRINTF( + info_buffers.statistics, TIP_("Mem:%.2fM, Peak: %.2fM"), rs->mem_used, rs->mem_peak); + } + info_statistics = info_buffers.statistics; } - BLI_timecode_string_from_time_simple( - info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime); - } - else { - spos += BLI_sprintf(spos, "| "); - } - - spos += BLI_sprintf(spos, TIP_("Time:%s "), info_time_str); - - /* statistics */ - if (rs->statstr) { - if (rs->statstr[0]) { - spos += BLI_sprintf(spos, "| %s ", rs->statstr); - } - } - else { - if (rs->mem_peak == 0.0f) { - spos += BLI_sprintf( - spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory); - } - else { - spos += BLI_sprintf(spos, TIP_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak); + if (info_statistics) { + ret_array[i++] = info_sep; + ret_array[i++] = info_statistics; + ret_array[i++] = info_space; } } - /* extra info */ - if (rs->infostr && rs->infostr[0]) { - spos += BLI_sprintf(spos, "| %s ", rs->infostr); - } - else if (error && error[0]) { - spos += BLI_sprintf(spos, "| %s ", error); + /* Extra info. */ + { + const char *info_extra = nullptr; + if (rs->infostr && rs->infostr[0]) { + info_extra = rs->infostr; + } + else if (error && error[0]) { + info_extra = error; + } + + if (info_extra) { + ret_array[i++] = info_sep; + ret_array[i++] = info_extra; + ret_array[i++] = info_space; + } } - /* very weak... but 512 characters is quite safe */ - if (spos >= str + IMA_MAX_RENDER_TEXT) { - if (G.debug & G_DEBUG) { + if (G.debug & G_DEBUG) { + if (BLI_string_len_array(ret_array, i) >= IMA_MAX_RENDER_TEXT) { printf("WARNING! renderwin text beyond limit\n"); } } + + BLI_assert(i < int(BOUNDED_ARRAY_TYPE_SIZE())); + BLI_string_join_array(ret, IMA_MAX_RENDER_TEXT, ret_array, i); } static void image_renderinfo_cb(void *rjv, RenderStats *rs) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 176070ef52d..4a1b5fda346 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1168,7 +1168,9 @@ static void rna_ParticleSystem_active_particle_target_index_set(struct PointerRN } } -static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *value) +static size_t rna_ParticleTarget_name_get_impl(PointerRNA *ptr, + char *value, + const size_t value_maxncpy) { ParticleTarget *pt = ptr->data; @@ -1184,29 +1186,32 @@ static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *value) } if (psys) { + int value_len; if (pt->ob) { - BLI_sprintf(value, "%s: %s", pt->ob->id.name + 2, psys->name); + value_len = BLI_snprintf_rlen( + value, value_maxncpy, "%s: %s", pt->ob->id.name + 2, psys->name); } else { - strcpy(value, psys->name); + value_len = BLI_strncpy_rlen(value, psys->name, value_maxncpy); } - } - else { - strcpy(value, TIP_("Invalid target!")); + return value_len; } } - else { - strcpy(value, TIP_("Invalid target!")); - } + + return BLI_strncpy_rlen(value, TIP_("Invalid target!"), value_maxncpy); +} + +static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *value) +{ + char value_buf[MAX_ID_NAME + MAX_ID_NAME + 64]; + const size_t value_buf_len = rna_ParticleTarget_name_get_impl(ptr, value_buf, sizeof(value_buf)); + memcpy(value, value_buf, value_buf_len + 1); } static int rna_ParticleTarget_name_length(PointerRNA *ptr) { - char tvalue[MAX_ID_NAME + MAX_ID_NAME + 64]; - - rna_ParticleTarget_name_get(ptr, tvalue); - - return strlen(tvalue); + char value_buf[MAX_ID_NAME + MAX_ID_NAME + 64]; + return rna_ParticleTarget_name_get_impl(ptr, value_buf, sizeof(value_buf)); } static int particle_id_check(const PointerRNA *ptr) @@ -1304,7 +1309,9 @@ static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int } } -static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *value) +static size_t rna_ParticleDupliWeight_name_get_impl(PointerRNA *ptr, + char *value, + const size_t value_maxncpy) { ParticleSettings *part = (ParticleSettings *)ptr->owner_id; psys_find_group_weights(part); @@ -1312,20 +1319,24 @@ static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *value) ParticleDupliWeight *dw = ptr->data; if (dw->ob) { - BLI_sprintf(value, "%s: %i", dw->ob->id.name + 2, dw->count); - } - else { - strcpy(value, "No object"); + return BLI_snprintf_rlen(value, value_maxncpy, "%s: %i", dw->ob->id.name + 2, dw->count); } + + return BLI_strncpy_rlen(value, "No object", value_maxncpy); +} + +static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *value) +{ + char value_buf[MAX_ID_NAME + 64]; + const size_t value_buf_len = rna_ParticleDupliWeight_name_get_impl( + ptr, value_buf, sizeof(value_buf)); + memcpy(value, value_buf, value_buf_len + 1); } static int rna_ParticleDupliWeight_name_length(PointerRNA *ptr) { - char tvalue[MAX_ID_NAME + 64]; - - rna_ParticleDupliWeight_name_get(ptr, tvalue); - - return strlen(tvalue); + char value_buf[MAX_ID_NAME + 64]; + return rna_ParticleDupliWeight_name_get_impl(ptr, value_buf, sizeof(value_buf)); } static const EnumPropertyItem *rna_Particle_type_itemf(bContext *UNUSED(C), diff --git a/source/blender/nodes/texture/nodes/node_texture_output.cc b/source/blender/nodes/texture/nodes/node_texture_output.cc index 6c129c51816..2cdd3d1710a 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.cc +++ b/source/blender/nodes/texture/nodes/node_texture_output.cc @@ -84,7 +84,8 @@ static void unique_name(bNode *node) STRNCPY(new_name, name); name = new_name; } - BLI_sprintf(new_name + new_len - 4, ".%03d", ++suffix); + int name_ofs = new_len - 4; + BLI_snprintf(new_name + name_ofs, sizeof(new_name) - name_ofs, ".%03d", ++suffix); } if (new_name[0] != '\0') { diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 97e82488a1c..fbdf196fc54 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -9,6 +9,7 @@ #include "BLI_math.h" #include "BLI_sort.h" #include "BLI_string.h" +#include "BLI_string_utils.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -4255,22 +4256,24 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype) char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]) { /* zero to ensure string is always NULL terminated */ - char *ret_ptr = ret; + const char *ret_array[4]; + int i = 0; if (htype & BM_VERT) { - ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMVert_Type.tp_name); + ret_array[i++] = BPy_BMVert_Type.tp_name; } if (htype & BM_EDGE) { - ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMEdge_Type.tp_name); + ret_array[i++] = BPy_BMEdge_Type.tp_name; } if (htype & BM_FACE) { - ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMFace_Type.tp_name); + ret_array[i++] = BPy_BMFace_Type.tp_name; } if (htype & BM_LOOP) { - ret_ptr += BLI_sprintf(ret_ptr, "/%s", BPy_BMLoop_Type.tp_name); + ret_array[i++] = BPy_BMLoop_Type.tp_name; } ret[0] = '('; - *ret_ptr++ = ')'; - *ret_ptr = '\0'; + int ret_ofs = BLI_string_join_array_by_sep_char(ret + 1, 30, '/', ret_array, i) + 1; + ret[ret_ofs] = ')'; + ret[ret_ofs + 1] = '\0'; return ret; } char *BPy_BMElem_StringFromHType(const char htype) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index b536c53e324..b03b249ea95 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -969,7 +969,8 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) PointerRNA ptr; const char *name; const char *type_id = NULL; - char type_fmt[64] = ""; + char type_lower[64]; + char type_count[16]; int type; PYRNA_PROP_CHECK_OBJ(self); @@ -982,13 +983,10 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) return NULL; } - /* This should never fail. */ + STRNCPY(type_lower, type_id); + BLI_str_tolower_ascii(type_lower, sizeof(type_lower)); + int len = -1; - char *c = type_fmt; - - while ((*c++ = tolower(*type_id++))) { - } - if (type == PROP_COLLECTION) { len = pyrna_prop_collection_length(self); } @@ -997,7 +995,10 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) } if (len != -1) { - BLI_sprintf(--c, "[%d]", len); + SNPRINTF(type_count, "[%d]", len); + } + else { + type_count[0] = '\0'; } /* If a pointer, try to print name of pointer target too. */ @@ -1006,8 +1007,9 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); if (name) { - ret = PyUnicode_FromFormat("", - type_fmt, + ret = PyUnicode_FromFormat("", + type_lower, + type_count, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); @@ -1019,12 +1021,13 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) PointerRNA r_ptr; if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { return PyUnicode_FromFormat( - "", type_fmt, RNA_struct_identifier(r_ptr.type)); + "", type_lower, type_count, RNA_struct_identifier(r_ptr.type)); } } - return PyUnicode_FromFormat("", - type_fmt, + return PyUnicode_FromFormat("", + type_lower, + type_count, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop)); }