diff --git a/extern/xdnd/xdnd.c b/extern/xdnd/xdnd.c index e8c51377e27..afd7156978f 100644 --- a/extern/xdnd/xdnd.c +++ b/extern/xdnd/xdnd.c @@ -464,8 +464,9 @@ static char *concat_string_list (char **t, int *bytes) break; if (!(t[n][0])) break; - strcpy (s + l, t[n]); - l += strlen (t[n]) + 1; + int t_size = strlen (t[n]) + 1; + memcpy (s + l, t[n], t_size); + l += t_size; } *bytes = l; s[l] = '\0'; diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cc b/intern/ghost/intern/GHOST_DropTargetWin32.cc index a7f642cdbb0..513f61b0b55 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cc +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cc @@ -270,10 +270,11 @@ void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *p_data_object) if (p_data_object->QueryGetData(&fmtetc) == S_OK) { if (p_data_object->GetData(&fmtetc, &stgmed) == S_OK) { char *str = (char *)::GlobalLock(stgmed.hGlobal); + int str_size = ::strlen(str) + 1; - tmp_string = (char *)::malloc(::strlen(str) + 1); + tmp_string = (char *)::malloc(str_size); if (tmp_string) { - ::strcpy(tmp_string, str); + ::memcpy(tmp_string, str, str_size); } /* Free memory. */ ::GlobalUnlock(stgmed.hGlobal); diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc index 58c14405792..7f46f2c8cd8 100644 --- a/source/blender/blenkernel/intern/action_test.cc +++ b/source/blender/blenkernel/intern/action_test.cc @@ -2,6 +2,8 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_string.h" + #include "BKE_action.h" #include "DNA_action_types.h" @@ -53,10 +55,10 @@ TEST(action_groups, ReconstructGroupsWithReordering) bActionGroup groupB = {nullptr}; bActionGroup groupC = {nullptr}; bActionGroup groupD = {nullptr}; - strcpy(groupA.name, "groupA"); - strcpy(groupB.name, "groupB"); - strcpy(groupC.name, "groupC"); - strcpy(groupD.name, "groupD"); + STRNCPY(groupA.name, "groupA"); + STRNCPY(groupB.name, "groupB"); + STRNCPY(groupC.name, "groupC"); + STRNCPY(groupD.name, "groupD"); BLI_addtail(&action.groups, &groupA); BLI_addtail(&action.groups, &groupB); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 75f95c20998..c0b551e684d 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -703,7 +703,7 @@ bool bone_autoside_name( { uint len; char basename[MAXBONENAME] = ""; - char extension[5] = ""; + const char *extension = NULL; len = strlen(name); if (len == 0) { @@ -723,18 +723,18 @@ bool bone_autoside_name( /* z-axis - vertical (top/bottom) */ if (IS_EQF(head, 0.0f)) { if (tail < 0) { - strcpy(extension, "Bot"); + extension = "Bot"; } else if (tail > 0) { - strcpy(extension, "Top"); + extension = "Top"; } } else { if (head < 0) { - strcpy(extension, "Bot"); + extension = "Bot"; } else { - strcpy(extension, "Top"); + extension = "Top"; } } } @@ -742,18 +742,18 @@ bool bone_autoside_name( /* y-axis - depth (front/back) */ if (IS_EQF(head, 0.0f)) { if (tail < 0) { - strcpy(extension, "Fr"); + extension = "Fr"; } else if (tail > 0) { - strcpy(extension, "Bk"); + extension = "Bk"; } } else { if (head < 0) { - strcpy(extension, "Fr"); + extension = "Fr"; } else { - strcpy(extension, "Bk"); + extension = "Bk"; } } } @@ -761,19 +761,19 @@ bool bone_autoside_name( /* x-axis - horizontal (left/right) */ if (IS_EQF(head, 0.0f)) { if (tail < 0) { - strcpy(extension, "R"); + extension = "R"; } else if (tail > 0) { - strcpy(extension, "L"); + extension = "L"; } } else { if (head < 0) { - strcpy(extension, "R"); + extension = "R"; /* XXX Shouldn't this be simple else, as for z and y axes? */ } else if (head > 0) { - strcpy(extension, "L"); + extension = "L"; } } } @@ -782,7 +782,7 @@ bool bone_autoside_name( * - truncate if there is an extension and it wouldn't be able to fit * - otherwise, just append to end */ - if (extension[0]) { + if (extension) { bool changed = true; while (changed) { /* remove extensions */ diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c index f9d918663be..efc098c16f8 100644 --- a/source/blender/blenlib/intern/string_utils.c +++ b/source/blender/blenlib/intern/string_utils.c @@ -133,14 +133,14 @@ size_t BLI_string_flip_side_name(char *name_dst, BLI_string_debug_size(name_dst, name_dst_maxncpy); size_t len; - char *prefix = alloca(name_dst_maxncpy); /* The part before the facing */ - char *suffix = alloca(name_dst_maxncpy); /* The part after the facing */ - char *replace = alloca(name_dst_maxncpy); /* The replacement string */ - char *number = alloca(name_dst_maxncpy); /* The number extension string */ + char *prefix = alloca(name_dst_maxncpy); /* The part before the facing */ + char *suffix = alloca(name_dst_maxncpy); /* The part after the facing */ + char *number = alloca(name_dst_maxncpy); /* The number extension string */ + const char *replace = NULL; char *index = NULL; bool is_set = false; - *prefix = *suffix = *replace = *number = '\0'; + *prefix = *suffix = *number = '\0'; /* always copy the name, since this can be called with an uninitialized string */ len = BLI_strncpy_rlen(name_dst, name_src, name_dst_maxncpy); @@ -169,19 +169,19 @@ size_t BLI_string_flip_side_name(char *name_dst, switch (name_dst[len - 1]) { case 'l': prefix[len - 1] = 0; - strcpy(replace, "r"); + replace = "r"; break; case 'r': prefix[len - 1] = 0; - strcpy(replace, "l"); + replace = "l"; break; case 'L': prefix[len - 1] = 0; - strcpy(replace, "R"); + replace = "R"; break; case 'R': prefix[len - 1] = 0; - strcpy(replace, "L"); + replace = "L"; break; default: is_set = false; @@ -193,22 +193,22 @@ size_t BLI_string_flip_side_name(char *name_dst, is_set = true; switch (name_dst[0]) { case 'l': - strcpy(replace, "r"); + replace = "r"; BLI_strncpy(suffix, name_dst + 1, name_dst_maxncpy); prefix[0] = 0; break; case 'r': - strcpy(replace, "l"); + replace = "l"; BLI_strncpy(suffix, name_dst + 1, name_dst_maxncpy); prefix[0] = 0; break; case 'L': - strcpy(replace, "R"); + replace = "R"; BLI_strncpy(suffix, name_dst + 1, name_dst_maxncpy); prefix[0] = 0; break; case 'R': - strcpy(replace, "L"); + replace = "L"; BLI_strncpy(suffix, name_dst + 1, name_dst_maxncpy); prefix[0] = 0; break; @@ -222,10 +222,10 @@ size_t BLI_string_flip_side_name(char *name_dst, if (((index = BLI_strcasestr(prefix, "right")) == prefix) || (index == prefix + len - 5)) { is_set = true; if (index[0] == 'r') { - strcpy(replace, "left"); + replace = "left"; } else { - strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left"); + replace = (index[1] == 'I' ? "LEFT" : "Left"); } *index = 0; BLI_strncpy(suffix, index + 5, name_dst_maxncpy); @@ -233,10 +233,10 @@ size_t BLI_string_flip_side_name(char *name_dst, else if (((index = BLI_strcasestr(prefix, "left")) == prefix) || (index == prefix + len - 4)) { is_set = true; if (index[0] == 'l') { - strcpy(replace, "right"); + replace = "right"; } else { - strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right"); + replace = (index[1] == 'E' ? "RIGHT" : "Right"); } *index = 0; BLI_strncpy(suffix, index + 4, name_dst_maxncpy); @@ -244,7 +244,7 @@ size_t BLI_string_flip_side_name(char *name_dst, } return BLI_snprintf_rlen( - name_dst, name_dst_maxncpy, "%s%s%s%s", prefix, replace, suffix, number); + name_dst, name_dst_maxncpy, "%s%s%s%s", prefix, replace ? replace : "", suffix, number); } /* Unique name utils. */ diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c index 9b603945a90..74c076f0604 100644 --- a/source/blender/datatoc/datatoc_icon.c +++ b/source/blender/datatoc/datatoc_icon.c @@ -36,17 +36,6 @@ /* -------------------------------------------------------------------- */ /* Utility functions */ -static int path_ensure_slash(char *path) -{ - int len = strlen(path); - if (len == 0 || path[len - 1] != SEP) { - path[len] = SEP; - path[len + 1] = '\0'; - return len + 1; - } - return len; -} - static bool path_test_extension(const char *filepath, const char *ext) { const size_t a = strlen(filepath); @@ -81,6 +70,25 @@ static const char *path_basename(const char *path) return filename ? filename + 1 : path; } +static bool path_join(char *filepath, + size_t filepath_maxncpy, + const char *dirpath, + const char *filename) +{ + int dirpath_len = strlen(dirpath); + if (dirpath_len && dirpath[dirpath_len - 1] == SEP) { + dirpath_len--; + } + const int filename_len = strlen(filename); + if (dirpath_len + 1 + filename_len + 1 > filepath_maxncpy) { + return false; + } + memcpy(filepath, dirpath, dirpath_len); + filepath[dirpath_len] = SEP; + memcpy(filepath + dirpath_len + 1, filename, filename_len + 1); + return true; +} + /* -------------------------------------------------------------------- */ /* Write a PNG from RGBA pixels */ @@ -392,8 +400,6 @@ static bool icondir_to_png(const char *path_src, const char *file_dst) DIR *dir; const struct dirent *fname; char filepath[1024]; - char *filename; - int path_str_len; int found = 0, fail = 0; struct IconMergeContext context; @@ -411,15 +417,12 @@ static bool icondir_to_png(const char *path_src, const char *file_dst) return false; } - strcpy(filepath, path_src); - path_str_len = path_ensure_slash(filepath); - filename = &filepath[path_str_len]; - while ((fname = readdir(dir)) != NULL) { if (path_test_extension(fname->d_name, ".dat")) { - - strcpy(filename, fname->d_name); - + if (!path_join(filepath, sizeof(filepath), path_src, fname->d_name)) { + printf("%s: path is too long (%s, %s)\n", __func__, path_src, fname->d_name); + return false; + } if (icon_merge(&context, filepath, &pixels_canvas, &canvas_w, &canvas_h)) { found++; } diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index b14d5b3bd4d..48586d83b85 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -526,7 +526,7 @@ static int rna_find_sdna_member(SDNA *sdna, return 0; } -static int rna_validate_identifier(const char *identifier, char *error, bool property) +static bool rna_validate_identifier(const char *identifier, bool property, const char **r_error) { int a = 0; @@ -548,15 +548,15 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro }; if (!isalpha(identifier[0])) { - strcpy(error, "first character failed isalpha() check"); - return 0; + *r_error = "first character failed isalpha() check"; + return false; } for (a = 0; identifier[a]; a++) { if (DefRNA.preprocess && property) { if (isalpha(identifier[a]) && isupper(identifier[a])) { - strcpy(error, "property names must contain lower case characters only"); - return 0; + *r_error = "property names must contain lower case characters only"; + return false; } } @@ -565,20 +565,20 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro } if (identifier[a] == ' ') { - strcpy(error, "spaces are not okay in identifier names"); - return 0; + *r_error = "spaces are not okay in identifier names"; + return false; } if (isalnum(identifier[a]) == 0) { - strcpy(error, "one of the characters failed an isalnum() check and is not an underscore"); - return 0; + *r_error = "one of the characters failed an isalnum() check and is not an underscore"; + return false; } } for (a = 0; kwlist[a]; a++) { if (STREQ(identifier, kwlist[a])) { - strcpy(error, "this keyword is reserved by Python"); - return 0; + *r_error = "this keyword is reserved by Python"; + return false; } } @@ -594,13 +594,13 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro for (a = 0; kwlist_prop[a]; a++) { if (STREQ(identifier, kwlist_prop[a])) { - strcpy(error, "this keyword is reserved by Python"); - return 0; + *r_error = "this keyword is reserved by Python"; + return false; } } } - return 1; + return true; } void RNA_identifier_sanitize(char *identifier, int property) @@ -907,9 +907,9 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN PropertyRNA *prop; if (DefRNA.preprocess) { - char error[512]; + const char *error = NULL; - if (rna_validate_identifier(identifier, error, false) == 0) { + if (!rna_validate_identifier(identifier, false, &error)) { CLOG_ERROR(&LOG, "struct identifier \"%s\" error - %s", identifier, error); DefRNA.error = true; } @@ -1269,9 +1269,9 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, PropertyRNA *prop; if (DefRNA.preprocess) { - char error[512]; + const char *error = NULL; - if (rna_validate_identifier(identifier, error, true) == 0) { + if (!rna_validate_identifier(identifier, true, &error)) { CLOG_ERROR( &LOG, "property identifier \"%s.%s\" - %s", CONTAINER_RNA_ID(cont), identifier, error); DefRNA.error = true; @@ -1290,8 +1290,8 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, } else { #ifndef NDEBUG - char error[512]; - if (rna_validate_identifier(identifier, error, true) == 0) { + const char *error = NULL; + if (!rna_validate_identifier(identifier, true, &error)) { CLOG_ERROR(&LOG, "runtime property identifier \"%s.%s\" - %s", CONTAINER_RNA_ID(cont), @@ -3477,8 +3477,8 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, void RNA_def_property_srna(PropertyRNA *prop, const char *type) { - char error[512]; - if (rna_validate_identifier(type, error, false) == 0) { + const char *error = NULL; + if (!rna_validate_identifier(type, false, &error)) { CLOG_ERROR(&LOG, "struct identifier \"%s\" error - %s", type, error); DefRNA.error = true; return; @@ -4247,9 +4247,8 @@ static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier) FunctionDefRNA *dfunc; if (DefRNA.preprocess) { - char error[512]; - - if (rna_validate_identifier(identifier, error, false) == 0) { + const char *error = NULL; + if (!rna_validate_identifier(identifier, false, &error)) { CLOG_ERROR(&LOG, "function identifier \"%s\" - %s", identifier, error); DefRNA.error = true; } diff --git a/source/blender/makesrna/intern/rna_object_api.cc b/source/blender/makesrna/intern/rna_object_api.cc index 33c59ccada9..a880b84b9d7 100644 --- a/source/blender/makesrna/intern/rna_object_api.cc +++ b/source/blender/makesrna/intern/rna_object_api.cc @@ -30,6 +30,8 @@ #include "rna_internal.h" /* own include */ +#define MESH_DM_INFO_STR_MAX 16384 + static const EnumPropertyItem space_items[] = { {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The most global space in Blender"}, {CONSTRAINT_SPACE_POSE, @@ -763,7 +765,7 @@ void rna_Object_me_eval_info( if (me_eval) { ret = BKE_mesh_debug_info(me_eval); if (ret) { - strcpy(result, ret); + BLI_strncpy(result, ret, MESH_DM_INFO_STR_MAX); MEM_freeN(ret); } } @@ -1329,7 +1331,8 @@ void RNA_api_object(StructRNA *srna) "(only needed if current Context's depsgraph is not suitable)"); RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR); /* weak!, no way to return dynamic string type */ - parm = RNA_def_string(func, "result", nullptr, 16384, "", "Requested information"); + parm = RNA_def_string( + func, "result", nullptr, MESH_DM_INFO_STR_MAX, "", "Requested information"); RNA_def_parameter_flags( parm, PROP_THICK_WRAP, ParameterFlag(0)); /* needed for string return value */ RNA_def_function_output(func, parm); diff --git a/source/blender/makesrna/intern/rna_ui.cc b/source/blender/makesrna/intern/rna_ui.cc index 15fe02e1ac7..06e3655ccaf 100644 --- a/source/blender/makesrna/intern/rna_ui.cc +++ b/source/blender/makesrna/intern/rna_ui.cc @@ -266,7 +266,7 @@ static StructRNA *rna_Panel_register(Main *bmain, RNA_pointer_create(nullptr, &RNA_Panel, &dummy_panel, &dummy_panel_ptr); /* We have to set default context! Else we get a void string... */ - strcpy(dummy_pt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + STRNCPY(dummy_pt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummy_panel_ptr, data, have_function) != 0) { @@ -286,7 +286,7 @@ static StructRNA *rna_Panel_register(Main *bmain, if ((1 << dummy_pt.region_type) & RGN_TYPE_HAS_CATEGORY_MASK) { if (dummy_pt.category[0] == '\0') { /* Use a fallback, otherwise an empty value will draw the panel in every category. */ - strcpy(dummy_pt.category, PNL_CATEGORY_FALLBACK); + STRNCPY(dummy_pt.category, PNL_CATEGORY_FALLBACK); # ifndef NDEBUG printf("%s '%s' misses category, please update the script\n", error_prefix, dummy_pt.idname); # endif @@ -989,7 +989,7 @@ static StructRNA *rna_Menu_register(Main *bmain, RNA_pointer_create(nullptr, &RNA_Menu, &dummy_menu, &dummy_menu_ptr); /* We have to set default context! Else we get a void string... */ - strcpy(dummy_mt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + STRNCPY(dummy_mt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); /* validate the python class */ if (validate(&dummy_menu_ptr, data, have_function) != 0) {