diff --git a/scripts/modules/blend_render_info.py b/scripts/modules/blend_render_info.py index 0ba02ab17fc..1d2b60619b1 100755 --- a/scripts/modules/blend_render_info.py +++ b/scripts/modules/blend_render_info.py @@ -113,6 +113,13 @@ def _read_blend_rend_chunk_from_file(blendfile, filepath): scene_name = blendfile.read(64) sizeof_data_left -= 64 + if b'\0' not in scene_name: + if sizeof_data_left >= 192: + # Assume new, up to 256 bytes name. + scene_name += blendfile.read(192) + sizeof_data_left -= 192 + if b'\0' not in scene_name: + scene_name = scene_name[:-1] + b'\0' scene_name = scene_name[:scene_name.index(b'\0')] # It's possible old blend files are not UTF8 compliant, use `surrogateescape`. diff --git a/source/blender/animrig/intern/action_test.cc b/source/blender/animrig/intern/action_test.cc index e34c3f47f88..d42f7024959 100644 --- a/source/blender/animrig/intern/action_test.cc +++ b/source/blender/animrig/intern/action_test.cc @@ -1130,14 +1130,25 @@ TEST_F(ActionLayersTest, conversion_to_layered) ASSERT_TRUE(bag->fcurve_array[0]->modifiers.first == nullptr); ASSERT_TRUE(bag->fcurve_array[1]->modifiers.first != nullptr); - Action *long_name_action = BKE_id_new( - bmain, "name_for_an_action_that_is_exactly_64_chars_which_is_MAX_ID_NAME"); + constexpr char id_name_max[] = + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3_____"; + BLI_STATIC_ASSERT(std::string::traits_type::length(id_name_max) == MAX_ID_NAME - 2 - 1, + "Wrong 'max length' name"); + Action *long_name_action = BKE_id_new(bmain, id_name_max); action_fcurve_ensure_legacy(bmain, long_name_action, "Long", nullptr, {"location", 0}); + /* The long name is shortened to make space for "_layered". */ + constexpr char id_name_max_converted[] = + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAME-3______" + "name_for_an_action_that_is_exactly_255_bytes_MAX_ID_NAM_layered"; + BLI_STATIC_ASSERT(std::string::traits_type::length(id_name_max_converted) == MAX_ID_NAME - 2 - 1, + "Wrong 'max length' name"); converted = convert_to_layered_action(*bmain, *long_name_action); - /* AC gets added automatically by Blender, the long name is shortened to make space for - * "_layered". */ - EXPECT_STREQ(converted->id.name, - "ACname_for_an_action_that_is_exactly_64_chars_which_is_MA_layered"); + EXPECT_STREQ(BKE_id_name(converted->id), id_name_max_converted); } TEST_F(ActionLayersTest, conversion_to_layered_action_groups) diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index 024da532e83..86be474b0cf 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -299,7 +299,7 @@ void AS_asset_library_remap_ids(const blender::bke::id::IDRemapper &mappings); * \param r_name: Returns the ID name on success. Optional (passing null is allowed). */ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference, - char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */], + char r_path_buffer[1282 /* FILE_MAX_LIBEXTRA */], char **r_dir, char **r_group, char **r_name); diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index de6b2414598..1f73928651d 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -103,7 +103,7 @@ void AS_asset_library_remap_ids(const bke::id::IDRemapper &mappings) } void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference, - char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */], + char r_path_buffer[1282 /* FILE_MAX_LIBEXTRA */], char **r_dir, char **r_group, char **r_name) @@ -129,7 +129,7 @@ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_re BLI_assert(!exploded->group_component.is_empty()); BLI_assert(!exploded->name_component.is_empty()); - BLI_strncpy(r_path_buffer, exploded->full_path->c_str(), 1090 /* #FILE_MAX_LIBEXTRA. */); + BLI_strncpy(r_path_buffer, exploded->full_path->c_str(), 1282 /* #FILE_MAX_LIBEXTRA. */); if (!exploded->dir_component.is_empty()) { r_path_buffer[exploded->dir_component.size()] = '\0'; diff --git a/source/blender/asset_system/intern/asset_representation.cc b/source/blender/asset_system/intern/asset_representation.cc index d130e856cbd..9e2f6d60014 100644 --- a/source/blender/asset_system/intern/asset_representation.cc +++ b/source/blender/asset_system/intern/asset_representation.cc @@ -132,7 +132,7 @@ std::string AssetRepresentation::full_library_path() const { std::string asset_path = full_path(); - char blend_path[/*FILE_MAX_LIBEXTRA*/ 1090]; + char blend_path[/*FILE_MAX_LIBEXTRA*/ 1282]; if (!BKE_blendfile_library_path_explode(asset_path.c_str(), blend_path, nullptr, nullptr)) { return {}; } diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index aadaf8cc32c..340b90b7cdd 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 21 +#define BLENDER_FILE_SUBVERSION 22 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenkernel/BKE_lib_id.hh b/source/blender/blenkernel/BKE_lib_id.hh index f6303f46d65..0fe6e22cec8 100644 --- a/source/blender/blenkernel/BKE_lib_id.hh +++ b/source/blender/blenkernel/BKE_lib_id.hh @@ -788,8 +788,8 @@ void BKE_main_lib_objects_recalc_all(Main *bmain); */ void BKE_main_id_repair_duplicate_names_listbase(Main *bmain, ListBase *lb); -#define MAX_ID_FULL_NAME (64 + 64 + 3 + 1) /* 64 is MAX_ID_NAME - 2 */ -#define MAX_ID_FULL_NAME_UI (MAX_ID_FULL_NAME + 3) /* Adds `keycode` two letters at beginning. */ +#define MAX_ID_FULL_NAME (256 + 256 + 3 + 1) /* 256 is MAX_ID_NAME - 2 */ +#define MAX_ID_FULL_NAME_UI (MAX_ID_FULL_NAME + 3) /* Adds 'keycode' two letters at beginning. */ /** * Generate full name of the data-block (without ID code, but with library if any). * diff --git a/source/blender/blenkernel/intern/asset_edit.cc b/source/blender/blenkernel/intern/asset_edit.cc index 001d7f9e6bb..90ad2c799a1 100644 --- a/source/blender/blenkernel/intern/asset_edit.cc +++ b/source/blender/blenkernel/intern/asset_edit.cc @@ -125,6 +125,11 @@ static std::string asset_blendfile_path_for_save(const bUserAssetLibrary &user_l std::min(sizeof(base_name_filesafe), size_t(base_name.size() + 1))); BLI_path_make_safe_filename(base_name_filesafe); + /* FIXME: MAX_ID_NAME & FILE_MAXFILE + * + * This already does not respect the FILE_MAXFILE max length of filenames for the final filepath + * it seems? + */ { const std::string filepath = root_path + SEP + base_name_filesafe + BLENDER_ASSET_FILE_SUFFIX; if (!BLI_is_file(filepath.c_str())) { diff --git a/source/blender/blenkernel/intern/lib_id_test.cc b/source/blender/blenkernel/intern/lib_id_test.cc index dd792c9b2ba..f139d64a06b 100644 --- a/source/blender/blenkernel/intern/lib_id_test.cc +++ b/source/blender/blenkernel/intern/lib_id_test.cc @@ -14,6 +14,8 @@ #include "DNA_ID.h" +#include + namespace blender::bke::tests { struct LibIDMainSortTestContext { @@ -163,13 +165,27 @@ TEST(lib_id_main_unique_name, local_ids_rename_existing_never) STRNCPY(future_name, "OB_BBBB"); EXPECT_FALSE(BKE_main_namemap_get_unique_name(*ctx.bmain, *id_c, future_name)); EXPECT_STREQ(future_name, "OB_BBBB"); + constexpr char long_name[] = + "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; + BLI_STATIC_ASSERT(std::string::traits_type::length(long_name) == MAX_ID_NAME - 2 - 1, + "Wrong 'max length' name"); + constexpr char long_name_shorten[] = + "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; + BLI_STATIC_ASSERT(std::string::traits_type::length(long_name_shorten) == MAX_ID_NAME - 2 - 2, + "Wrong 'max length' name"); /* Name too long, needs to be truncated. */ - STRNCPY(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); + STRNCPY(future_name, long_name); change_name(ctx.bmain, id_a, future_name, IDNewNameMode::RenameExistingNever); EXPECT_STREQ(id_a->name + 2, future_name); - EXPECT_STREQ(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); + EXPECT_STREQ(future_name, long_name); EXPECT_TRUE(BKE_main_namemap_get_unique_name(*ctx.bmain, *id_c, future_name)); - EXPECT_STREQ(future_name, "OB_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); + EXPECT_STREQ(future_name, long_name_shorten); } TEST(lib_id_main_unique_name, local_ids_rename_existing_always) @@ -303,7 +319,7 @@ TEST(lib_id_main_unique_name, linked_ids_1) static void change_name_global(Main *bmain, ID *id, const char *name) { BKE_main_namemap_remove_id(*bmain, *id); - BLI_strncpy(id->name + 2, name, MAX_NAME); + BLI_strncpy(id->name + 2, name, MAX_ID_NAME - 2); BKE_main_global_namemap_get_unique_name(*bmain, *id, id->name + 2); @@ -415,17 +431,45 @@ TEST(lib_id_main_unique_name, ids_sorted_by_default_with_libraries) TEST(lib_id_main_unique_name, name_too_long_handling) { LibIDMainSortTestContext ctx; - const char *name_a = "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated"; - const char *name_b = "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123456"; - const char *name_c = "Name_That_Has_Too_Long_Number_Suffix.1234567890"; + constexpr char name_a[] = + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated"; + BLI_STATIC_ASSERT(std::string::traits_type::length(name_a) > MAX_ID_NAME - 2, + "Wrong 'max length' name"); + constexpr char name_a_shorten[] = + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated_" + "Long_Name_That_Does_Not_Fit_Into_Max"; + BLI_STATIC_ASSERT(std::string::traits_type::length(name_a_shorten) == MAX_ID_NAME - 2 - 1, + "Wrong 'max length' name"); + constexpr char name_b[] = + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123456"; + BLI_STATIC_ASSERT(std::string::traits_type::length(name_b) > MAX_ID_NAME - 2, + "Wrong 'max length' name"); + constexpr char name_b_shorten[] = + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix_____" + "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123"; + BLI_STATIC_ASSERT(std::string::traits_type::length(name_b_shorten) == MAX_ID_NAME - 2 - 1, + "Wrong 'max length' name"); + constexpr char name_c[] = "Name_That_Has_Too_Long_Number_Suffix.1234567890"; + BLI_STATIC_ASSERT(std::string::traits_type::length(name_c) < MAX_ID_NAME - 2, + "Wrong 'max length' name"); ID *id_a = static_cast(BKE_id_new(ctx.bmain, ID_OB, name_a)); ID *id_b = static_cast(BKE_id_new(ctx.bmain, ID_OB, name_b)); ID *id_c = static_cast(BKE_id_new(ctx.bmain, ID_OB, name_c)); - EXPECT_STREQ(id_a->name + 2, "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_"); - EXPECT_STREQ(id_b->name + 2, "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123"); - EXPECT_STREQ(id_c->name + 2, "Name_That_Has_Too_Long_Number_Suffix.1234567890"); /* Unchanged */ + EXPECT_STREQ(BKE_id_name(*id_a), name_a_shorten); + EXPECT_STREQ(BKE_id_name(*id_b), name_b_shorten); + EXPECT_STREQ(BKE_id_name(*id_c), name_c); /* Unchanged */ EXPECT_TRUE(BKE_main_namemap_validate(*ctx.bmain)); diff --git a/source/blender/blenlib/intern/path_utils.cc b/source/blender/blenlib/intern/path_utils.cc index bcedf44c35b..bd5207e37af 100644 --- a/source/blender/blenlib/intern/path_utils.cc +++ b/source/blender/blenlib/intern/path_utils.cc @@ -133,6 +133,12 @@ void BLI_path_sequence_encode(char *path, { BLI_string_debug_size(path, path_maxncpy); + /* FIXME: MAX_ID_NAME & FILE_MAXFILE + * + * As this function directly works on a full file path (typically a FILE_MAX long char buffer), + * and does not perform any check on the filename part of the path, it can easily generate final + * paths containing a filename longer than the max supported length (FILE_MAXFILE). + */ BLI_snprintf(path, path_maxncpy, "%s%.*d%s", head, numlen, std::max(0, pic), tail); } diff --git a/source/blender/editors/include/UI_interface_types.hh b/source/blender/editors/include/UI_interface_types.hh index 9ce071e00b4..f7bac69f166 100644 --- a/source/blender/editors/include/UI_interface_types.hh +++ b/source/blender/editors/include/UI_interface_types.hh @@ -12,8 +12,8 @@ struct bContext; struct uiLayout; /* names */ -#define UI_MAX_DRAW_STR 400 -#define UI_MAX_NAME_STR 128 +#define UI_MAX_DRAW_STR 550 +#define UI_MAX_NAME_STR 256 #define UI_MAX_SHORTCUT_STR 64 /* Menu Callbacks */ diff --git a/source/blender/editors/sculpt_paint/brush_asset_ops.cc b/source/blender/editors/sculpt_paint/brush_asset_ops.cc index 7086a6a34d1..e9ba3db327e 100644 --- a/source/blender/editors/sculpt_paint/brush_asset_ops.cc +++ b/source/blender/editors/sculpt_paint/brush_asset_ops.cc @@ -153,6 +153,12 @@ static wmOperatorStatus brush_asset_save_as_exec(bContext *C, wmOperator *op) /* Determine file path to save to. */ PropertyRNA *name_prop = RNA_struct_find_property(op->ptr, "name"); + /* FIXME: MAX_ID_NAME & FILE_MAXFILE + * + * This `name` should be `MAX_ID_NAME - 2` long. + * + * This name might also be used as filename for the saved asset, thus hitting the size issue + * between ID names and file names (FILE_MAXFILE). */ char name[MAX_NAME] = ""; if (RNA_property_is_set(op->ptr, name_prop)) { RNA_property_string_get(op->ptr, name_prop, name); diff --git a/source/blender/editors/space_file/filelist.hh b/source/blender/editors/space_file/filelist.hh index 8f03d7f4239..b02b1ed2bfc 100644 --- a/source/blender/editors/space_file/filelist.hh +++ b/source/blender/editors/space_file/filelist.hh @@ -82,7 +82,7 @@ void filelist_init_icons(); void filelist_free_icons(); void filelist_file_get_full_path(const FileList *filelist, const FileDirEntry *file, - char r_filepath[/*FILE_MAX_LIBEXTRA*/ 1090]); + char r_filepath[/*FILE_MAX_LIBEXTRA*/ 1282]); bool filelist_file_is_preview_pending(const FileList *filelist, const FileDirEntry *file); /** * \return True if a new preview request was pushed, false otherwise (e.g. because the preview is @@ -121,7 +121,7 @@ bool filelist_is_dir(const FileList *filelist, const char *path); /** * May modify in place given `dirpath`, which is expected to be #FILE_MAX_LIBEXTRA length. */ -void filelist_setdir(FileList *filelist, char dirpath[/*FILE_MAX_LIBEXTRA*/ 1090]); +void filelist_setdir(FileList *filelist, char dirpath[/*FILE_MAX_LIBEXTRA*/ 1282]); /** * Limited version of full update done by space_file's file_refresh(), diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index f81f6dded59..8b70d7571e6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -1364,6 +1364,17 @@ static void draw_selected_name( char frame[16]; } info_buffers; + /* Info can contain: + * - 1 frame number `(7 + 2)`. + * - 1 collection name `(MAX_ID_NAME - 2 + 3)`. + * - 1 object name `(MAX_ID_NAME - 2)`. + * - 1 object data name `(MAX_ID_NAME - 2)`. + * - 2 non-ID data names (bones, shapekeys...) `(MAX_NAME * 2)`. + * - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`. + * - 1 SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room! + * - 1 marker name `(MAX_NAME + 3)`. + */ + SNPRINTF(info_buffers.frame, "(%d)", cfra); info_array[i++] = info_buffers.frame; @@ -1377,15 +1388,6 @@ static void draw_selected_name( } } - /* Info can contain: - * - A frame `(7 + 2)`. - * - A collection name `(MAX_NAME + 3)`. - * - 3 object names `(MAX_NAME)`. - * - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`. - * - A SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room! - * - A marker name `(MAX_NAME + 3)`. - */ - /* get name of marker on current frame (if available) */ const char *markern = BKE_scene_find_marker_name(scene, cfra); @@ -1477,9 +1479,12 @@ static void draw_selected_name( } BLI_assert(i < int(ARRAY_SIZE(info_array))); - char info[300]; - /* It's expected there will be enough room for the buffer (if not, increase it). */ + + char info[MAX_ID_NAME * 4]; + /* It's expected there will be enough room for the whole string in the the buffer. If not, + * increase it. */ BLI_assert(BLI_string_len_array(info_array, i) < sizeof(info)); + BLI_string_join_array(info, sizeof(info), info_array, i); *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 2bd7af4709b..f5baf354d13 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -359,8 +359,8 @@ enum { * provides a common handle to place all data in double-linked lists. */ -/* 2 characters for ID code and 64 for actual name */ -#define MAX_ID_NAME 66 +/* 2 characters for ID code and 256 for actual name */ +#define MAX_ID_NAME 258 /** #ID_Runtime_Remap.status */ enum { @@ -412,7 +412,15 @@ typedef struct ID { /** If the ID is an asset, this pointer is set. Owning pointer. */ struct AssetMetaData *asset_data; - char name[/*MAX_ID_NAME*/ 66]; + /** + * Main identifier for this data-block. Must be unique within the ID name-space (defined by its + * type, and owning #Library). + * + * The first two bytes are always the #ID_Type code of the data-block's type. + * + * One critical usage is to reference external linked data. */ + char name[/*MAX_ID_NAME*/ 258]; + /** * ID_FLAG_... flags report on status of the data-block this ID belongs to * (persistent, saved to and read from .blend). @@ -531,7 +539,7 @@ typedef struct LibraryWeakReference { char library_filepath[/*FILE_MAX*/ 1024]; /** May be different from the current local ID name. */ - char library_id_name[/*MAX_ID_NAME*/ 66]; + char library_id_name[/*MAX_ID_NAME*/ 258]; char _pad[2]; } LibraryWeakReference; diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 881ca18dd99..6ea580eb95c 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -1184,7 +1184,7 @@ typedef struct ActionSlot { * * \see #AnimData::slot_name */ - char identifier[/*MAX_ID_NAME*/ 66]; + char identifier[/*MAX_ID_NAME*/ 258]; /** * Type of ID-block that this slot is intended for. diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 44a9e3c7727..85771d64254 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -441,7 +441,7 @@ typedef struct NlaStrip { * \note Most code should not write to this field directly, but use functions from * `blender::animrig::nla` instead, see ANIM_nla.hh. */ - char last_slot_identifier[66]; /* MAX_ID_NAME */ + char last_slot_identifier[/* MAX_ID_NAME */ 258]; char _pad0[2]; /** F-Curves for controlling this strip's influence and timing */ /* TODO: move out? */ @@ -677,7 +677,7 @@ typedef struct AnimData { * * \see #ActionSlot::name */ - char last_slot_identifier[66]; /* MAX_ID_NAME */ + char last_slot_identifier[/* MAX_ID_NAME */ 258]; uint8_t _pad0[2]; /** @@ -686,7 +686,7 @@ typedef struct AnimData { */ bAction *tmpact; int32_t tmp_slot_handle; - char tmp_last_slot_identifier[66]; /* MAX_ID_NAME */ + char tmp_last_slot_identifier[/* MAX_ID_NAME */ 258]; uint8_t _pad1[2]; /* nla-tracks */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 2446df97652..907b0fdf7c8 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -303,7 +303,7 @@ typedef struct bActionConstraint { float eval_time; /* Only used when flag ACTCON_USE_EVAL_TIME is set. */ struct bAction *act; int32_t action_slot_handle; - char last_slot_identifier[/*MAX_ID_NAME*/ 66]; + char last_slot_identifier[/*MAX_ID_NAME*/ 258]; char _pad1[2]; char subtarget[/*MAX_NAME*/ 64]; } bActionConstraint; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 5655a8f352e..67ab1fce395 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -396,10 +396,10 @@ typedef struct FileSelectParams { /** * Directory. * - * \note #FILE_MAX_LIBEXTRA == `1024 + 66`, this is for extreme case when 1023 length path + * \note #FILE_MAX_LIBEXTRA == `1024 + 258`, this is for extreme case when 1023 length path * needs to be linked in, where `foo.blend/Armature` need adding. */ - char dir[/*FILE_MAX_LIBEXTRA*/ 1090]; + char dir[/*FILE_MAX_LIBEXTRA*/ 1282]; char file[/*FILE_MAXFILE*/ 256]; char renamefile[/*FILE_MAXFILE*/ 256]; diff --git a/source/blender/render/intern/render_result.cc b/source/blender/render/intern/render_result.cc index 8f3651c489d..8e314cdd37b 100644 --- a/source/blender/render/intern/render_result.cc +++ b/source/blender/render/intern/render_result.cc @@ -1034,6 +1034,11 @@ static void render_result_exr_file_cache_path(Scene *sce, root = root_buf; } + /* FIXME: MAX_ID_NAME & FILE_MAXFILE + * + * If #filename is already long (it is initialized from the blend-file name itself), adding the + * scene name can cause the file name to be truncated. + */ SNPRINTF(filename_full, "cached_RR_%s_%s_%s.exr", filename, sce->id.name + 2, path_hexdigest); BLI_path_join(r_path, FILE_CACHE_MAX, root, filename_full); diff --git a/tests/files/io_tests/fbx/max2025-longnames.fbx b/tests/files/io_tests/fbx/max2025-longnames.fbx index 7e82c836dfc..d7930d34da4 100644 --- a/tests/files/io_tests/fbx/max2025-longnames.fbx +++ b/tests/files/io_tests/fbx/max2025-longnames.fbx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ac81b86b89910406e919dc51fe77d44cf27e0aa581695c8a3268f14b219caf0 -size 74896 +oid sha256:971ef1c87a73a6abceff2aff78731d75bc91b0e96cb9fe22f3925dcf0fb31975 +size 71452 diff --git a/tests/files/io_tests/fbx/reference/max2025-longnames.txt b/tests/files/io_tests/fbx/reference/max2025-longnames.txt index a9e0d7121ac..4b378f13b9f 100644 --- a/tests/files/io_tests/fbx/reference/max2025-longnames.txt +++ b/tests/files/io_tests/fbx/reference/max2025-longnames.txt @@ -135,7 +135,7 @@ -0.210 0.000 0.978 0.000 - props: int:MaxHandle=3 - anim act:Take 001 slot:OBArmature blend:REPLACE drivers:0 -- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_A' MESH data:'Mesh.002' par:'Armature' +- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_' MESH data:'Mesh.002' par:'Armature' - pos 0.679, 0.000, 15.811 - rot -1.571, 0.000, 0.000 (XYZ) - scl 1.000, 1.000, 1.000 @@ -144,7 +144,7 @@ - 1 modifiers - ARMATURE 'Armature' - props: int:MaxHandle=10 -- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Ar' MESH data:'Mesh' par:'Armature' +- Obj 'Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_Long_Name_To_Test_Importer_Handling_Of_Names_That_Are_Too_Long_To_Fit_Box_With_A_L' MESH data:'Mesh' par:'Armature' - pos 0.679, 0.000, -0.945 - rot -1.571, 0.000, 0.000 (XYZ) - scl 1.000, 1.000, 1.000 @@ -153,17 +153,17 @@ - 1 modifiers - ARMATURE 'Armature' - props: int:MaxHandle=2 -- Obj 'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' MESH data:'Mesh.003' +- Obj 'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye' MESH data:'Mesh.003' - pos -0.261, -0.829, 0.000 - rot 0.000, 0.000, 0.000 (XYZ) - scl 0.025, 0.025, 0.025 - - anim act:Take 001 slot:OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se blend:REPLACE drivers:0 + - anim act:Take 001 slot:OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye blend:REPLACE drivers:0 - props: int:MaxHandle=14 -- Obj 'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_' LIGHT data:'Light' +- Obj 'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_' LIGHT data:'Light' - pos 0.567, -0.741, 0.000 - rot 0.000, 0.000, 0.000 (XYZ) - scl 0.025, 0.025, 0.025 - - anim act:Take 001 slot:OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_ blend:REPLACE drivers:0 + - anim act:Take 001 slot:OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_ blend:REPLACE drivers:0 - props: int:MaxHandle=15 - Obj 'Sphere_Parented_To_Bone' MESH data:'Mesh.001' par:'Armature' par_type:BONE par_bone:'Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.002' - pos 6.099, -21.143, 2.790 @@ -224,7 +224,7 @@ - fcu 'pose.bones["Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.003"].rotation_quaternion[1]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Likewise_Here_Is_A_Bone_With_A_Long_Name_To_See_What_Happen.003' - (1.000, 0.000) lh:(-0.667, 0.000 AUTO_CLAMPED) rh:(2.667, 0.000 AUTO_CLAMPED) - (6.000, 0.000) lh:(4.333, 0.000 AUTO_CLAMPED) rh:(7.667, 0.000 AUTO_CLAMPED) - - Channelbag slot 'OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' curves:9 + - Channelbag slot 'OBBox_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_See_What_Happens_Here_Box_Ye' curves:9 - fcu 'location[0]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' - (1.000, -0.261) lh:(0.000, -0.261 AUTO_CLAMPED) rh:(2.000, -0.261 AUTO_CLAMPED) - (4.000, 0.211) lh:(3.000, 0.211 AUTO_CLAMPED) rh:(5.000, 0.211 AUTO_CLAMPED) @@ -252,7 +252,7 @@ - fcu 'scale[2]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Box_Yellow_That_Is_Animated_And_Also_With_A_Long_Name_Let_Us_Se' - (1.000, 0.025) lh:(0.000, 0.025 AUTO_CLAMPED) rh:(2.000, 0.025 AUTO_CLAMPED) - (4.000, 0.025) lh:(3.000, 0.025 AUTO_CLAMPED) rh:(5.000, 0.025 AUTO_CLAMPED) - - Channelbag slot 'OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_' curves:9 + - Channelbag slot 'OBPoint_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_Name_Here_Point_Light_Object_Color_Blue_Light_' curves:9 - fcu 'location[0]' smooth:CONT_ACCEL extra:CONSTANT keyframes:2 grp:'Point_Light_Object_Color_Blue_Light_Color_Animated_With_A_Long_' - (1.000, 0.567) lh:(-0.667, 0.567 AUTO_CLAMPED) rh:(2.667, 0.567 AUTO_CLAMPED) - (6.000, 1.148) lh:(4.333, 1.148 AUTO_CLAMPED) rh:(7.667, 1.148 AUTO_CLAMPED) diff --git a/tests/files/io_tests/obj/invalid_syntax.obj b/tests/files/io_tests/obj/invalid_syntax.obj index 8b70f6b5586..d6cdb2b89e0 100644 --- a/tests/files/io_tests/obj/invalid_syntax.obj +++ b/tests/files/io_tests/obj/invalid_syntax.obj @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556b5e37a5e2f3c81e7ec846ab33a639d18cde361d21a16183188c1dd4f347fe -size 762 +oid sha256:37d58400e2e8259deeaa95dc0dad5c9f99bf3a01deeb705f362649bd9193ac33 +size 1020 diff --git a/tests/files/io_tests/obj/reference/invalid_syntax.txt b/tests/files/io_tests/obj/reference/invalid_syntax.txt index e8a114baa6c..e6c5dbc4303 100644 --- a/tests/files/io_tests/obj/reference/invalid_syntax.txt +++ b/tests/files/io_tests/obj/reference/invalid_syntax.txt @@ -1,5 +1,5 @@ ==== Meshes: 1 -- Mesh 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon' vtx:3 face:1 loop:3 edge:3 +- Mesh 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan' vtx:3 face:1 loop:3 edge:3 - 0 1 2 - 0/2 0/1 1/2 - attr 'position' FLOAT_VECTOR POINT @@ -22,7 +22,7 @@ - (1.000, 0.750) ==== Objects: 1 -- Obj 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon' MESH data:'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon' +- Obj 'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan' MESH data:'ObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHandleObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLongerThanBlenderCanHan' - pos 0.000, 0.000, 0.000 - rot 1.571, 0.000, 0.000 (XYZ) - scl 1.000, 1.000, 1.000 diff --git a/tests/python/bl_animation_action.py b/tests/python/bl_animation_action.py index 04b583e057d..51adfa21e37 100644 --- a/tests/python/bl_animation_action.py +++ b/tests/python/bl_animation_action.py @@ -68,24 +68,36 @@ class ActionSlotCreationTest(unittest.TestCase): self.action.slots.new('UNSPECIFIED', "Bob") def test_long_identifier(self): - # Test a 65-character identifier, using a 63-character name. This is the - # maximum length allowed (the DNA field is MAX_ID_NAME=66 long, which + # Test a 257-character identifier, using a 255-character name. This is the + # maximum length allowed (the DNA field is MAX_ID_NAME=258 long, which # includes the trailing zero byte). - long_but_ok_name = "This name is so long! It might look long, but it is just right!" + long_but_ok_name = ( + "This name is so long! It might look long, but it is just right! " + "This name is so long! It might look long, but it is just right! " + "This name is so long! It might look long, but it is just right! " + "This name is so long! It might look long, but it is just right!" + ) + assert (len(long_but_ok_name) == 255) slot_ok = self.action.slots.new('OBJECT', long_but_ok_name) self.assertEqual(long_but_ok_name, slot_ok.name_display, "this name should fit") self.assertEqual('OB' + long_but_ok_name, slot_ok.identifier, "this identifier should fit") # Test one character more. - too_long_name = "This name is so long! It might look long, and that it is indeed." - too_long_name_truncated = too_long_name[:63] + too_long_name = ( + "This name is so long! It might look long, and that it is indeed." + "This name is so long! It might look long, and that it is indeed." + "This name is so long! It might look long, and that it is indeed." + "This name is so long! It might look long, and that it is indeed." + ) + assert (len(too_long_name) == 256) + too_long_name_truncated = too_long_name[:255] slot_long = self.action.slots.new('OBJECT', too_long_name) self.assertEqual(too_long_name_truncated, slot_long.name_display, "this name should be truncated") self.assertEqual('OB' + too_long_name_truncated, slot_long.identifier, "this identifier should be truncated") # Test with different trailing character. - other_long_name = "This name is so long! It might look long, and that it is indeed!" - truncated_and_unique = other_long_name[:59] + ".001" + other_long_name = too_long_name[:-1] + "!" + truncated_and_unique = other_long_name[:251] + ".001" slot_long2 = self.action.slots.new('OBJECT', too_long_name) self.assertEqual(truncated_and_unique, slot_long2.name_display, "this name should be truncated and made unique")