From 58bd360d6ba20c23b5f4110b5bc757e128b4066e Mon Sep 17 00:00:00 2001 From: elasota <1137273+elasota@users.noreply.github.com> Date: Mon, 25 Dec 2023 21:21:20 -0500 Subject: [PATCH] Handle backslashes in paths on Windows --- lib/helper.c | 17 +++++++++++++++++ lib/libunshield.c | 9 +++++++++ src/unshield.c | 22 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/helper.c b/lib/helper.c index 25ed46a..3978506 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -44,8 +44,16 @@ long int unshield_get_path_max(Unshield* unshield) char *unshield_get_base_directory_name(Unshield *unshield) { long int path_max = unshield_get_path_max(unshield); char *p = strrchr(unshield->filename_pattern, '/'); +#ifdef WIN32 + char *pbs = strrchr(unshield->filename_pattern, '\\'); +#endif char *dirname = malloc(path_max); +#ifdef WIN32 + if (NULL != pbs && (NULL == p || pbs > p)) + p = pbs; +#endif + if (p) { strncpy(dirname, unshield->filename_pattern, path_max); if ((unsigned int) (p - unshield->filename_pattern) > path_max) { @@ -91,11 +99,20 @@ FILE* unshield_fopen_for_reading(Unshield* unshield, int index, const char* suff char* filename = get_filename(unshield, index, suffix); char* dirname = unshield_get_base_directory_name(unshield); const char *q; +#ifdef WIN32 + const char *qbs; +#endif struct dirent *dent = NULL; DIR *sourcedir = NULL; long int path_max = unshield_get_path_max(unshield); q=strrchr(filename,'/'); +#ifdef WIN32 + qbs = strrchr(filename, '\\'); + if (NULL != qbs && (NULL == q || qbs > q)) + q = qbs; +#endif + if (q) q++; else diff --git a/lib/libunshield.c b/lib/libunshield.c index e3dd06a..7e5e8ec 100644 --- a/lib/libunshield.c +++ b/lib/libunshield.c @@ -98,6 +98,15 @@ static bool unshield_create_filename_pattern(Unshield* unshield, const char* fil char pattern[256]; char* prefix = strdup(filename); char* p = strrchr(prefix, '/'); +#ifdef WIN32 + char *pbs = strrchr(prefix, '\\'); +#endif + +#ifdef WIN32 + if (NULL != pbs && (NULL == p || pbs > p)) + p = pbs; +#endif + if (!p) p = prefix; diff --git a/src/unshield.c b/src/unshield.c index 470a397..b3a70da 100644 --- a/src/unshield.c +++ b/src/unshield.c @@ -96,15 +96,35 @@ static bool make_sure_directory_exists(const char* directory)/*{{{*/ p+=2; else if (0 == strncmp(p, "../", 3)) p+=3; +#ifdef WIN32 + if ('\\' == *p) + p++; + else if (0 == strncmp(p, ".\\", 2)) + p += 2; + else if (0 == strncmp(p, "..\\", 3)) + p += 3; +#endif else { + int is_win_root = 0; const char* slash = strchr(p, '/'); +#ifdef WIN32 + const char* backslash = strchr(p, '/'); + if (NULL != backslash && (NULL == slash || backslash < slash)) + slash = backslash; +#endif + current = strdup(directory); if (slash) current[slash-directory] = '\0'; - if (stat(current, &dir_stat) < 0) +#ifdef WIN32 + if (slash - directory == 2 && current[1] == ':') + is_win_root = 1; +#endif + + if (!is_win_root && stat(current, &dir_stat) < 0) { #if defined (__MINGW32__) || defined (_WIN32) if (_mkdir(current) < 0)