diff options
author | David Robillard <d@drobilla.net> | 2022-07-06 15:07:51 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-07-17 17:14:39 -0400 |
commit | 572e6fb63fb9570b429d39c5f52a4b7025fd15ee (patch) | |
tree | 34b01580a05c730530b7925b8730ea9902a43d18 | |
parent | 62cad71a1a36aabc550362d8fa4a61752076f7c9 (diff) | |
download | lilv-572e6fb63fb9570b429d39c5f52a4b7025fd15ee.tar.gz lilv-572e6fb63fb9570b429d39c5f52a4b7025fd15ee.tar.bz2 lilv-572e6fb63fb9570b429d39c5f52a4b7025fd15ee.zip |
Avoid incorrect use of mkstemp in tests
This was an overly hasty switch from race-prone alternatives to mkstemp, but it
did not actually account for the fact that mkstemp creates the file. This
resulted in leaking the file handle, and trying to open it twice, which made
the tests fail on Windows/MinGW.
-rw-r--r-- | test/test.lv2/test.c | 72 | ||||
-rw-r--r-- | test/test_util.c | 37 |
2 files changed, 72 insertions, 37 deletions
diff --git a/test/test.lv2/test.c b/test/test.lv2/test.c index 2be34b4..1dc7076 100644 --- a/test/test.lv2/test.c +++ b/test/test.lv2/test.c @@ -1,6 +1,6 @@ /* Lilv Test Plugin - Copyright 2011-2019 David Robillard <d@drobilla.net> + Copyright 2011-2022 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -22,9 +22,9 @@ #include "lv2/state/state.h" #include "lv2/urid/urid.h" -#ifdef _MSC_VER -# include <io.h> -# define mkstemp(pat) _mktemp(pat) +#ifdef _WIN32 +# define _WIN32_LEAN_AND_MEAN +# include <windows.h> #endif #include <stdint.h> @@ -34,8 +34,6 @@ #define TEST_URI "http://example.org/lilv-test-plugin" -#define TMP_TEMPLATE "lilv_testXXXXXX" - enum { TEST_INPUT = 0, TEST_OUTPUT = 1, TEST_CONTROL = 2 }; typedef struct { @@ -46,7 +44,7 @@ typedef struct { LV2_URID atom_Float; } uris; - char tmp_file_path[sizeof(TMP_TEMPLATE)]; + char* tmp_dir_path; char* rec_file_path; FILE* rec_file; @@ -55,6 +53,35 @@ typedef struct { unsigned num_runs; } Test; +static char* +temp_directory_path(void) +{ +#ifdef _WIN32 + const DWORD len = GetTempPath(0, NULL); + char* const buf = (char*)calloc(len, 1); + if (GetTempPath(len, buf) == 0) { + free(buf); + return NULL; + } + + return buf; +#else + const char* const tmpdir = getenv("TMPDIR"); + if (tmpdir) { + const size_t tmpdir_len = strlen(tmpdir); + char* const result = (char*)calloc(tmpdir_len + 1, 1); + + memcpy(result, tmpdir, tmpdir_len + 1); + return result; + } + + char* const result = (char*)calloc(6, 1); + + memcpy(result, "/tmp/", 6); + return result; +#endif +} + static void cleanup(LV2_Handle instance) { @@ -67,6 +94,7 @@ cleanup(LV2_Handle instance) test->free_path->free_path(test->free_path->handle, test->rec_file_path); } + free(test->tmp_dir_path); free(instance); } @@ -104,8 +132,7 @@ instantiate(const LV2_Descriptor* descriptor, return NULL; } - strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1); - mkstemp(test->tmp_file_path); + test->tmp_dir_path = temp_directory_path(); LV2_State_Make_Path* make_path = NULL; @@ -272,15 +299,30 @@ save(LV2_Handle instance, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); if (map_path) { - FILE* file = fopen(plugin->tmp_file_path, "w"); + const char* const file_name = "temp_file.txt"; + const size_t file_name_len = strlen(file_name); + const size_t dir_path_len = strlen(plugin->tmp_dir_path); + char* const tmp_file_path = + (char*)calloc(dir_path_len + file_name_len + 1, 1); + + memcpy(tmp_file_path, plugin->tmp_dir_path, dir_path_len); + memcpy(tmp_file_path + dir_path_len, file_name, file_name_len + 1); + + FILE* file = fopen(tmp_file_path, "w"); + if (!file) { + fprintf(stderr, "error: Failed to open file %s\n", tmp_file_path); + free(tmp_file_path); + return LV2_STATE_ERR_UNKNOWN; + } + fprintf(file, "Hello\n"); fclose(file); - char* apath = - map_path->abstract_path(map_path->handle, plugin->tmp_file_path); - char* apath2 = - map_path->abstract_path(map_path->handle, plugin->tmp_file_path); + + char* apath = map_path->abstract_path(map_path->handle, tmp_file_path); + char* apath2 = map_path->abstract_path(map_path->handle, tmp_file_path); + free(tmp_file_path); if (strcmp(apath, apath2)) { - fprintf(stderr, "ERROR: Path %s != %s\n", apath, apath2); + fprintf(stderr, "error: Path %s != %s\n", apath, apath2); } store(callback_data, diff --git a/test/test_util.c b/test/test_util.c index 8c8f36a..c140e34 100644 --- a/test/test_util.c +++ b/test/test_util.c @@ -1,5 +1,5 @@ /* - Copyright 2007-2020 David Robillard <d@drobilla.net> + Copyright 2007-2022 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -14,44 +14,30 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define _XOPEN_SOURCE 600 /* for mkstemp */ - #undef NDEBUG -#ifdef _WIN32 -# include "lilv_internal.h" -#endif - #include "../src/filesystem.h" -#ifdef _WIN32 -# include <io.h> -# define mkstemp(pat) _mktemp(pat) -#endif +#include "lilv/lilv.h" #include <assert.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> int main(void) { assert(!lilv_path_canonical(NULL)); - char a_path[16]; - char b_path[16]; - strncpy(a_path, "copy_a_XXXXXX", sizeof(a_path)); - strncpy(b_path, "copy_b_XXXXXX", sizeof(b_path)); - mkstemp(a_path); - mkstemp(b_path); + char* const dir = lilv_create_temporary_directory("lilv_test_util_XXXXXX"); + char* const a_path = lilv_path_join(dir, "copy_a_XXXXXX"); + char* const b_path = lilv_path_join(dir, "copy_b_XXXXXX"); - FILE* fa = fopen(a_path, "w"); - FILE* fb = fopen(b_path, "w"); + FILE* const fa = fopen(a_path, "w"); + FILE* const fb = fopen(b_path, "w"); fprintf(fa, "AA\n"); fprintf(fb, "AB\n"); - fclose(fa); fclose(fb); + fclose(fa); assert(lilv_copy_file("does/not/exist", "copy")); assert(lilv_copy_file(a_path, "not/a/dir/copy")); @@ -63,5 +49,12 @@ main(void) assert(!lilv_file_equals(a_path, "does/not/exist")); assert(!lilv_file_equals("does/not/exist", "/does/not/either")); + assert(!lilv_remove(a_path)); + assert(!lilv_remove(b_path)); + assert(!lilv_remove(dir)); + + lilv_free(b_path); + lilv_free(a_path); + lilv_free(dir); return 0; } |