Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-09-04 07:22:44 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-09-04 09:59:54 +0300
commite6194e735791b42feb51e810a4910a41d999d3bf (patch)
tree95889982ba8c6bc88f5bdfb2eded77159d81ca89
parent716682365c6bcc1b5f757232ce1d2499b0d062a9 (diff)
RNA: support extracting names from paths without allocating memory
Support extracting identifiers RNA paths into fixed size buffer since the maximum size of the identifier is known all cases. - Add BLI_str_unescape_ex to support limiting the destination buffer. - Add BLI_str_quoted_substr to copy values into a fixed size buffer.
-rw-r--r--source/blender/blenkernel/intern/action_bones.cc6
-rw-r--r--source/blender/blenkernel/intern/fcurve.c24
-rw-r--r--source/blender/blenlib/BLI_string.h12
-rw-r--r--source/blender/blenlib/intern/string.c97
-rw-r--r--source/blender/editors/animation/anim_deps.c7
-rw-r--r--source/blender/editors/animation/anim_filter.c25
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c30
-rw-r--r--source/blender/editors/animation/keyframes_general.c9
-rw-r--r--source/blender/editors/animation/keyframing.c16
-rw-r--r--source/blender/editors/armature/pose_select.c8
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c8
-rw-r--r--source/blender/io/collada/BCAnimationCurve.cpp5
-rw-r--r--source/blender/io/collada/BCAnimationSampler.cpp5
13 files changed, 153 insertions, 99 deletions
diff --git a/source/blender/blenkernel/intern/action_bones.cc b/source/blender/blenkernel/intern/action_bones.cc
index b8d185e6a81..1f2b7360b70 100644
--- a/source/blender/blenkernel/intern/action_bones.cc
+++ b/source/blender/blenkernel/intern/action_bones.cc
@@ -28,6 +28,7 @@
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
#include "MEM_guardedalloc.h"
@@ -36,12 +37,11 @@ namespace blender::bke {
void BKE_action_find_fcurves_with_bones(const bAction *action, FoundFCurveCallback callback)
{
LISTBASE_FOREACH (FCurve *, fcu, &action->curves) {
- char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- if (!bone_name) {
+ char bone_name[MAXBONENAME];
+ if (!BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) {
continue;
}
callback(fcu, bone_name);
- MEM_freeN(bone_name);
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index fb6cd5871f4..8e9c504dcbf 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -346,30 +346,30 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con
return 0;
}
+ const size_t quotedName_size = strlen(dataName) + 1;
+ char *quotedName = alloca(quotedName_size);
+
/* Search each F-Curve one by one. */
for (fcu = src->first; fcu; fcu = fcu->next) {
/* Check if quoted string matches the path. */
if (fcu->rna_path == NULL) {
continue;
}
-
- char *quotedName = BLI_str_quoted_substrN(fcu->rna_path, dataPrefix);
- if (quotedName == NULL) {
+ /* Skipping names longer than `quotedName_size` is OK since we're after an exact match. */
+ if (!BLI_str_quoted_substr(fcu->rna_path, dataPrefix, quotedName, quotedName_size)) {
+ continue;
+ }
+ if (!STREQ(quotedName, dataName)) {
continue;
}
/* Check if the quoted name matches the required name. */
- if (STREQ(quotedName, dataName)) {
- LinkData *ld = MEM_callocN(sizeof(LinkData), __func__);
-
- ld->data = fcu;
- BLI_addtail(dst, ld);
+ LinkData *ld = MEM_callocN(sizeof(LinkData), __func__);
- matches++;
- }
+ ld->data = fcu;
+ BLI_addtail(dst, ld);
- /* Always free the quoted string, since it needs freeing. */
- MEM_freeN(quotedName);
+ matches++;
}
/* Return the number of matches. */
return matches;
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index c20376c42b9..eab39433796 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -65,7 +65,10 @@ bool BLI_str_quoted_substr_range(const char *__restrict str,
char *BLI_str_quoted_substrN(const char *__restrict str,
const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL() ATTR_MALLOC;
-
+bool BLI_str_quoted_substr(const char *__restrict str,
+ const char *__restrict prefix,
+ char *result,
+ size_t result_maxlen);
char *BLI_str_replaceN(const char *__restrict str,
const char *__restrict substr_old,
const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT
@@ -97,8 +100,15 @@ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy)
ATTR_NONNULL();
+size_t BLI_str_unescape_ex(char *__restrict dst,
+ const char *__restrict src,
+ const size_t src_maxncpy,
+ /* Additional arguments. */
+ const size_t dst_maxncpy,
+ bool *r_is_complete) ATTR_NONNULL();
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy)
ATTR_NONNULL();
+
const char *BLI_str_escape_find_quote(const char *str) ATTR_NONNULL();
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 0be8700810e..fab5e44de25 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -360,6 +360,27 @@ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const si
return len;
}
+BLI_INLINE bool str_unescape_pair(char c_next, char *r_out)
+{
+#define CASE_PAIR(value_src, value_dst) \
+ case value_src: { \
+ *r_out = value_dst; \
+ return true; \
+ }
+ switch (c_next) {
+ CASE_PAIR('"', '"'); /* Quote. */
+ CASE_PAIR('\\', '\\'); /* Backslash. */
+ CASE_PAIR('t', '\t'); /* Tab. */
+ CASE_PAIR('n', '\n'); /* Newline. */
+ CASE_PAIR('r', '\r'); /* Carriage return. */
+ CASE_PAIR('a', '\a'); /* Bell. */
+ CASE_PAIR('b', '\b'); /* Backspace. */
+ CASE_PAIR('f', '\f'); /* Form-feed. */
+ }
+#undef CASE_PAIR
+ return false;
+}
+
/**
* This roughly matches C and Python's string escaping with double quotes - `"`.
*
@@ -368,31 +389,53 @@ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const si
*
* \param dst: The destination string, at least the size of `strlen(src) + 1`.
* \param src: The escaped source string.
- * \param dst_maxncpy: The maximum number of bytes allowable to copy.
+ * \param src_maxncpy: The maximum number of bytes allowable to copy from `src`.
+ * \param dst_maxncpy: The maximum number of bytes allowable to copy into `dst`.
+ * \param r_is_complete: Set to true when
+ */
+size_t BLI_str_unescape_ex(char *__restrict dst,
+ const char *__restrict src,
+ const size_t src_maxncpy,
+ /* Additional arguments to #BLI_str_unescape */
+ const size_t dst_maxncpy,
+ bool *r_is_complete)
+{
+ size_t len = 0;
+ bool is_complete = true;
+ for (const char *src_end = src + src_maxncpy; (src < src_end) && *src; src++) {
+ if (UNLIKELY(len == dst_maxncpy)) {
+ is_complete = false;
+ break;
+ }
+ char c = *src;
+ if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ src++;
+ }
+ dst[len++] = c;
+ }
+ dst[len] = 0;
+ *r_is_complete = is_complete;
+ return len;
+}
+
+/**
+ * See #BLI_str_unescape_ex doc-string.
+ *
+ * This function makes the assumption that `dst` always has
+ * at least `src_maxncpy` bytes available.
+ *
+ * Use #BLI_str_unescape_ex if `dst` has a smaller fixed size.
*
- * \note This is used for parsing animation paths in blend files.
+ * \note This is used for parsing animation paths in blend files (runs often).
*/
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy)
{
size_t len = 0;
- for (size_t i = 0; i < src_maxncpy && (*src != '\0'); i++, src++) {
+ for (const char *src_end = src + src_maxncpy; (src < src_end) && *src; src++) {
char c = *src;
- if (c == '\\') {
- char c_next = *(src + 1);
- if (((c_next == '"') && ((void)(c = '"'), true)) || /* Quote. */
- ((c_next == '\\') && ((void)(c = '\\'), true)) || /* Backslash. */
- ((c_next == 't') && ((void)(c = '\t'), true)) || /* Tab. */
- ((c_next == 'n') && ((void)(c = '\n'), true)) || /* Newline. */
- ((c_next == 'r') && ((void)(c = '\r'), true)) || /* Carriage return. */
- ((c_next == 'a') && ((void)(c = '\a'), true)) || /* Bell. */
- ((c_next == 'b') && ((void)(c = '\b'), true)) || /* Backspace. */
- ((c_next == 'f') && ((void)(c = '\f'), true))) /* Form-feed. */
- {
- i++;
- src++;
- }
+ if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ src++;
}
-
dst[len++] = c;
}
dst[len] = 0;
@@ -491,6 +534,24 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
return result;
}
+bool BLI_str_quoted_substr(const char *__restrict str,
+ const char *__restrict prefix,
+ char *result,
+ size_t result_maxlen)
+{
+ int start_match_ofs, end_match_ofs;
+ if (!BLI_str_quoted_substr_range(str, prefix, &start_match_ofs, &end_match_ofs)) {
+ return false;
+ }
+ const size_t escaped_len = (size_t)(end_match_ofs - start_match_ofs);
+ bool is_complete;
+ BLI_str_unescape_ex(result, str + start_match_ofs, escaped_len, result_maxlen, &is_complete);
+ if (is_complete == false) {
+ *result = '\0';
+ }
+ return is_complete;
+}
+
/**
* string with all instances of substr_old replaced with substr_new,
* Returns a copy of the c-string \a str into a newly #MEM_mallocN'd
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index 916d4232f03..97679723d84 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -206,16 +206,17 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale)
BLI_assert(GS(owner_id->name) == ID_SCE);
Scene *scene = (Scene *)owner_id;
FCurve *fcu = (FCurve *)ale->data;
+ Sequence *seq = NULL;
/* Only affect if F-Curve involves sequence_editor.sequences. */
- char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- if (seq_name == NULL) {
+ char seq_name[sizeof(seq->name)];
+ if (!BLI_str_quoted_substr(fcu->rna_path, "sequences_all[", seq_name, sizeof(seq_name))) {
return;
}
/* Check if this strip is selected. */
Editing *ed = SEQ_editing_get(scene);
- Sequence *seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false);
+ seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false);
MEM_freeN(seq_name);
if (seq == NULL) {
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 104540e2257..b12e0ae5cab 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1061,13 +1061,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
if (GS(owner_id->name) == ID_OB) {
Object *ob = (Object *)owner_id;
- char *bone_name;
+ bPoseChannel *pchan = NULL;
+ char bone_name[sizeof(pchan->name)];
/* Only consider if F-Curve involves `pose.bones`. */
- if (fcu->rna_path && (bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["))) {
+ if (fcu->rna_path &&
+ BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) {
/* Get bone-name, and check if this bone is selected. */
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- MEM_freeN(bone_name);
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
/* check whether to continue or skip */
if (pchan && pchan->bone) {
@@ -1097,17 +1098,17 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
else if (GS(owner_id->name) == ID_SCE) {
Scene *scene = (Scene *)owner_id;
- char *seq_name;
+ Sequence *seq = NULL;
+ char seq_name[sizeof(seq->name)];
/* Only consider if F-Curve involves `sequence_editor.sequences`. */
- if (fcu->rna_path && (seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["))) {
+ if (fcu->rna_path &&
+ BLI_str_quoted_substr(fcu->rna_path, "sequences_all[", seq_name, sizeof(seq_name))) {
/* Get strip name, and check if this strip is selected. */
- Sequence *seq = NULL;
Editing *ed = SEQ_editing_get(scene);
if (ed) {
seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false);
}
- MEM_freeN(seq_name);
/* Can only add this F-Curve if it is selected. */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
@@ -1139,14 +1140,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
else if (GS(owner_id->name) == ID_NT) {
bNodeTree *ntree = (bNodeTree *)owner_id;
- char *node_name;
+ bNode *node = NULL;
+ char node_name[sizeof(node->name)];
/* Check for selected nodes. */
- if (fcu->rna_path && (node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["))) {
- bNode *node = NULL;
+ if (fcu->rna_path &&
+ (BLI_str_quoted_substr(fcu->rna_path, "nodes[", node_name, sizeof(node_name)))) {
/* Get strip name, and check if this strip is selected. */
node = nodeFindNodebyName(ntree, node_name);
- MEM_freeN(node_name);
/* Can only add this F-Curve if it is selected. */
if (node) {
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index eda87cf1897..33b4882927a 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -106,23 +106,14 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
* - If a pointer just refers to the ID-block, then don't repeat this info
* since this just introduces clutter.
*/
- if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
- /* perform string 'chopping' to get "Bone Name : Constraint Name" */
- char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
- char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints[");
+
+ char pchanName[256], constName[256];
+ if (BLI_str_quoted_substr(fcu->rna_path, "bones[", pchanName, sizeof(pchanName)) &&
+ BLI_str_quoted_substr(fcu->rna_path, "constraints[", constName, sizeof(constName))) {
/* assemble the string to display in the UI... */
- structname = BLI_sprintfN(
- "%s : %s", pchanName ? pchanName : "", constName ? constName : "");
+ structname = BLI_sprintfN("%s : %s", pchanName, constName);
free_structname = 1;
-
- /* free the temp names */
- if (pchanName) {
- MEM_freeN(pchanName);
- }
- if (constName) {
- MEM_freeN(constName);
- }
}
else if (ptr.data != ptr.owner_id) {
PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
@@ -139,18 +130,15 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
* displaying the struct name alone is no meaningful information (and also cannot be
* filtered well), same for modifiers. So display strip name alongside as well. */
if (GS(ptr.owner_id->name) == ID_SCE) {
- if (BLI_str_startswith(fcu->rna_path, "sequence_editor.sequences_all[\"")) {
+ char stripname[256];
+ if (BLI_str_quoted_substr(
+ fcu->rna_path, "sequence_editor.sequences_all[", stripname, sizeof(stripname))) {
if (strstr(fcu->rna_path, ".transform.") || strstr(fcu->rna_path, ".crop.") ||
strstr(fcu->rna_path, ".modifiers[")) {
- char *stripname = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- const char *structname_all = BLI_sprintfN(
- "%s : %s", stripname ? stripname : "", structname);
+ const char *structname_all = BLI_sprintfN("%s : %s", stripname, structname);
if (free_structname) {
MEM_freeN((void *)structname);
}
- if (stripname) {
- MEM_freeN(stripname);
- }
structname = structname_all;
free_structname = 1;
}
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 9f3fe239113..ec33a42af3b 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -761,11 +761,10 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
Object *ob = (Object *)aci->id;
- char *bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
- if (bone_name) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- MEM_freeN(bone_name);
-
+ bPoseChannel *pchan;
+ char bone_name[sizeof(pchan->name)];
+ if (BLI_str_quoted_substr(aci->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) {
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (pchan) {
aci->is_bone = true;
}
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 292d665caca..8dc4aed9f0e 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -2218,11 +2218,11 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->mode & OB_MODE_POSE) {
if (fcu->rna_path) {
/* Get bone-name, and check if this bone is selected. */
- char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- if (bone_name) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- MEM_freeN(bone_name);
-
+ bPoseChannel *pchan = NULL;
+ char bone_name[sizeof(pchan->name)];
+ if (BLI_str_quoted_substr(
+ fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) {
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
/* Delete if bone is selected. */
if ((pchan) && (pchan->bone)) {
if (pchan->bone->flag & BONE_SELECTED) {
@@ -2323,13 +2323,11 @@ static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op)
bPoseChannel *pchan = NULL;
/* Get bone-name, and check if this bone is selected. */
- char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- if (bone_name == NULL) {
+ char bone_name[sizeof(pchan->name)];
+ if (!BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) {
continue;
}
-
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- MEM_freeN(bone_name);
/* skip if bone is not selected */
if ((pchan) && (pchan->bone)) {
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 4db8569a7d2..e5b8983af93 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -1106,12 +1106,12 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
/* only items related to this object will be relevant */
if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) {
- char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones[");
- if (boneName == NULL) {
+ bPoseChannel *pchan = NULL;
+ char boneName[sizeof(pchan->name)];
+ if (!BLI_str_quoted_substr(ksp->rna_path, "bones[", boneName, sizeof(boneName))) {
continue;
}
- bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName);
- MEM_freeN(boneName);
+ pchan = BKE_pose_channel_find_name(pose, boneName);
if (pchan) {
/* select if bone is visible and can be affected */
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index 98e00c20170..8f896512410 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -145,15 +145,15 @@ static void autokeyframe_pose(
if (act) {
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
/* only insert keyframes for this F-Curve if it affects the current bone */
- char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
- if (pchanName == NULL) {
+ char pchan_name[sizeof(pchan->name)];
+ if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
continue;
}
/* only if bone name matches too...
* NOTE: this will do constraints too, but those are ok to do here too?
*/
- if (STREQ(pchanName, pchan->name)) {
+ if (STREQ(pchan_name, pchan->name)) {
insert_keyframe(bmain,
reports,
id,
@@ -166,8 +166,6 @@ static void autokeyframe_pose(
&nla_cache,
flag);
}
-
- MEM_freeN(pchanName);
}
}
}
diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp
index 82d8b6e9ff3..005197c9027 100644
--- a/source/blender/io/collada/BCAnimationCurve.cpp
+++ b/source/blender/io/collada/BCAnimationCurve.cpp
@@ -173,10 +173,9 @@ std::string BCAnimationCurve::get_animation_name(Object *ob) const
name = "";
}
else {
- char *boneName = BLI_str_quoted_substrN(fcurve->rna_path, "pose.bones[");
- if (boneName) {
+ char boneName[MAXBONENAME];
+ if (BLI_str_quoted_substr(fcurve->rna_path, "pose.bones[", boneName, sizeof(boneName))) {
name = id_name(ob) + "_" + std::string(boneName);
- MEM_freeN(boneName);
}
else {
name = "";
diff --git a/source/blender/io/collada/BCAnimationSampler.cpp b/source/blender/io/collada/BCAnimationSampler.cpp
index d2bde193c0a..953af5adffc 100644
--- a/source/blender/io/collada/BCAnimationSampler.cpp
+++ b/source/blender/io/collada/BCAnimationSampler.cpp
@@ -447,10 +447,9 @@ void BCAnimationSampler::initialize_curves(BCAnimationCurveMap &curves, Object *
for (; fcu; fcu = fcu->next) {
object_type = BC_ANIMATION_TYPE_OBJECT;
if (ob->type == OB_ARMATURE) {
- char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- if (boneName) {
+ char boneName[MAXBONENAME];
+ if (BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", boneName, sizeof(boneName))) {
object_type = BC_ANIMATION_TYPE_BONE;
- MEM_freeN(boneName);
}
}