From be43077b1be49eab4e7362cebe0ffbaa18bd54b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Oct 2025 07:46:58 +0000 Subject: [PATCH] Fix: crash printing integers in IDP_reprN Regression in [0] caused printing integers to crash. While this function isn't widely used it could crash logging key-map items. Also add tests for IDP_reprN. Ref !148109 [0]: 92cf9dd2f2d7f4d8d380d4b1dcc17f6c2b5b175d --- .../blender/blenkernel/intern/idprop_test.cc | 38 +++++++++++++++++++ .../blender/blenkernel/intern/idprop_utils.cc | 9 +++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/idprop_test.cc b/source/blender/blenkernel/intern/idprop_test.cc index fdb78e6fc07..e2e9363774a 100644 --- a/source/blender/blenkernel/intern/idprop_test.cc +++ b/source/blender/blenkernel/intern/idprop_test.cc @@ -93,4 +93,42 @@ TEST(idproperties, SyncGroupValues) IDP_FreeProperty(group2); } +TEST(idproperties, ReprGroup) +{ + auto repr_fn = [](IDProperty *prop) -> std::string { + uint result_len; + char *c_str = IDP_reprN(prop, &result_len); + std::string result = std::string(c_str, result_len); + MEM_freeN(c_str); + return result; + }; + + IDProperty *group = idprop::create_group("test").release(); + + EXPECT_EQ(repr_fn(group), "{}"); + + IDP_AddToGroup(group, idprop::create("a", 1).release()); + IDP_AddToGroup(group, idprop::create("b", 0.5f).release()); + IDP_AddToGroup(group, idprop::create_bool("c", true).release()); + IDP_AddToGroup(group, idprop::create_bool("d", false).release()); + IDP_AddToGroup(group, idprop::create("e", "ABC (escape \" \\)").release()); + IDP_AddToGroup(group, idprop::create("f", Span({-1, 0, 1})).release()); + IDP_AddToGroup(group, idprop::create("g", Span({-0.5f, 0.0f, 0.5f})).release()); + IDP_AddToGroup(group, idprop::create_group("h").release()); + + EXPECT_EQ(repr_fn(group), + "{" + "\"a\": 1, " + "\"b\": 0.5, " + "\"c\": True, " + "\"d\": False, " + "\"e\": \"ABC (escape \\\" \\\\)\", " + "\"f\": [-1, 0, 1], " + "\"g\": [-0.5, 0, 0.5], " + "\"h\": {}" + "}"); + + IDP_FreeProperty(group); +} + } // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/idprop_utils.cc b/source/blender/blenkernel/intern/idprop_utils.cc index d86f12f66ef..161ccdd2a39 100644 --- a/source/blender/blenkernel/intern/idprop_utils.cc +++ b/source/blender/blenkernel/intern/idprop_utils.cc @@ -100,10 +100,13 @@ static void idp_repr_fn_recursive(ReprState *state, const IDProperty *prop) break; } case IDP_INT: { - if (const IDPropertyUIDataEnumItem *item = IDP_EnumItemFind(prop)) { - STR_APPEND_FMT("%s", item->name); + if (const IDPropertyUIDataEnumItem *item = prop->ui_data ? IDP_EnumItemFind(prop) : nullptr) + { + STR_APPEND_STR_QUOTE(item->name); + } + else { + STR_APPEND_FMT("%d", IDP_int_get(prop)); } - STR_APPEND_FMT("%d", IDP_int_get(prop)); break; } case IDP_FLOAT: {