Skip to content

Commit

Permalink
Handle backslashes in paths on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
elasota committed Dec 28, 2023
1 parent 3f25349 commit fb27a63
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
20 changes: 18 additions & 2 deletions lib/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ 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, '/');
char *p = unshield_get_last_path_separator(unshield->filename_pattern);
char *dirname = malloc(path_max);

if (p) {
Expand Down Expand Up @@ -95,7 +95,7 @@ FILE* unshield_fopen_for_reading(Unshield* unshield, int index, const char* suff
DIR *sourcedir = NULL;
long int path_max = unshield_get_path_max(unshield);

q=strrchr(filename,'/');
q=unshield_get_last_path_separator(filename);
if (q)
q++;
else
Expand Down Expand Up @@ -202,6 +202,22 @@ uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset)
return NULL;
}

/**
Returns the last path separator in a filesystem path
*/
char *unshield_get_last_path_separator(char *path)
{
char *p = strrchr(path, '/');

#ifdef WIN32
char *pbs = strrchr(path, '\\');

if (NULL != pbs && (NULL == p || pbs > p))
return pbs;
#endif

return p;
}

static int unshield_strlen_utf16(const uint16_t* utf16)
{
Expand Down
1 change: 1 addition & 0 deletions lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ bool unshield_read_common_header(uint8_t** buffer, CommonHeader* common);
const char* unshield_get_utf8_string(Header* header, const void* buffer);
const char* unshield_header_get_string(Header* header, uint32_t offset);
uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset);
char *unshield_get_last_path_separator(char *path);

static inline void* unshield_fopen(Unshield* unshield, const char *filename, const char *modes)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/libunshield.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static bool unshield_create_filename_pattern(Unshield* unshield, const char* fil
{
char pattern[256];
char* prefix = strdup(filename);
char* p = strrchr(prefix, '/');
char* p = unshield_get_last_path_separator(prefix);
if (!p)
p = prefix;

Expand Down
22 changes: 21 additions & 1 deletion src/unshield.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit fb27a63

Please sign in to comment.