From 501854e4ee0a7ad5f1f0274be8fae76e16e604ec Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Oct 2020 16:31:11 +0100 Subject: Fix T81421: "Saving As..." a blend file with a Script node file path filled with 1023 symbols crashes Blender. Usual lack of protection against buffer overflows when manipulating strings. Also add some basic tests for `BLI_path_rel`. --- source/blender/blenlib/intern/path_util.c | 2 +- source/blender/blenlib/tests/BLI_path_util_test.cc | 50 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index f3afef80c3e..758feef6093 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -639,7 +639,7 @@ void BLI_path_rel(char *file, const char *relfile) } /* don't copy the slash at the beginning */ - r += BLI_strcpy_rlen(r, q + 1); + r += BLI_strncpy_rlen(r, q + 1, FILE_MAX - (r - res)); #ifdef WIN32 BLI_str_replace_char(res + 2, '/', '\\'); diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc index 5556062233e..5ec057a8501 100644 --- a/source/blender/blenlib/tests/BLI_path_util_test.cc +++ b/source/blender/blenlib/tests/BLI_path_util_test.cc @@ -600,3 +600,53 @@ TEST(path_util, PathExtension) EXPECT_STREQ(".abc", BLI_path_extension("C:\\some.def\\file.abc")); EXPECT_STREQ(".001", BLI_path_extension("Text.001")); } + +/* BLI_path_rel. */ + +#define PATH_REL(abs_path, ref_path, rel_path) \ + { \ + char path[FILE_MAX]; \ + BLI_strncpy(path, abs_path, sizeof(path)); \ + BLI_path_rel(path, ref_path); \ + EXPECT_STREQ(rel_path, path); \ + } \ + void(0) + +TEST(path_util, PathRelPath) +{ + PATH_REL("/foo/bar/blender.blend", "/foo/bar/", "//blender.blend"); + PATH_REL("/foo/bar/blender.blend", "/foo/bar", "//bar/blender.blend"); + + /* Check for potential buffer overflows. */ + { + char abs_path_in[FILE_MAX]; + abs_path_in[0] = '/'; + for (int i = 1; i < FILE_MAX - 1; i++) { + abs_path_in[i] = 'A'; + } + abs_path_in[FILE_MAX - 1] = '\0'; + char abs_path_out[FILE_MAX]; + abs_path_out[0] = '/'; + abs_path_out[1] = '/'; + for (int i = 2; i < FILE_MAX - 1; i++) { + abs_path_out[i] = 'A'; + } + abs_path_out[FILE_MAX - 1] = '\0'; + PATH_REL(abs_path_in, "/", abs_path_out); + + const char *ref_path_in = "/foo/bar/"; + const size_t ref_path_in_len = strlen(ref_path_in); + strcpy(abs_path_in, ref_path_in); + for (int i = ref_path_in_len; i < FILE_MAX - 1; i++) { + abs_path_in[i] = 'A'; + } + abs_path_in[FILE_MAX - 1] = '\0'; + abs_path_out[0] = '/'; + abs_path_out[1] = '/'; + for (int i = 2; i < FILE_MAX - ((int)ref_path_in_len - 1); i++) { + abs_path_out[i] = 'A'; + } + abs_path_out[FILE_MAX - (ref_path_in_len - 1)] = '\0'; + PATH_REL(abs_path_in, ref_path_in, abs_path_out); + } +} -- cgit v1.2.3