Fix glob()
[wimlib] / programs / imagex-win32.c
index 3dc51d981311ed629238f616221b56c3e571c6bf..166485005308ead71bb54b1f1b6508babea06f5c 100644 (file)
@@ -25,6 +25,20 @@ int glob(const char *pattern, int flags,
        int ret;
        size_t nspaces;
 
+       const char *backslash, *forward_slash, *end_slash;
+       size_t prefix_len;
+
+       backslash = strrchr(pattern, '\\');
+       end_slash = strrchr(pattern, '/');
+
+       if (backslash > end_slash)
+               end_slash = backslash;
+
+       if (end_slash)
+               prefix_len = end_slash - pattern + 1;
+       else
+               prefix_len = 0;
+
        /* This function does not support all functionality of the POSIX glob(),
         * so make sure the parameters are consistent with supported
         * functionality. */
@@ -49,7 +63,7 @@ int glob(const char *pattern, int flags,
        pglob->gl_pathv = NULL;
        nspaces = 0;
        do {
-               char *filename;
+               char *path;
                if (pglob->gl_pathc == nspaces) {
                        size_t new_nspaces;
                        char **pathv;
@@ -62,10 +76,16 @@ int glob(const char *pattern, int flags,
                        pglob->gl_pathv = pathv;
                        nspaces = new_nspaces;
                }
-               filename = strdup(dat.cFileName);
-               if (!filename)
+               size_t filename_len = strlen(dat.cFileName);
+               size_t len_needed = prefix_len + filename_len;
+
+               path = malloc(len_needed + 1);
+               if (!path)
                        goto oom;
-               pglob->gl_pathv[pglob->gl_pathc++] = filename;
+
+               memcpy(path, pattern, prefix_len);
+               memcpy(path + prefix_len, dat.cFileName, filename_len + 1);
+               pglob->gl_pathv[pglob->gl_pathc++] = path;
        } while (FindNextFileA(hFind, &dat));
        err = GetLastError();
        CloseHandle(hFind);
@@ -93,7 +113,7 @@ void globfree(glob_t *pglob)
        size_t i;
        for (i = 0; i < pglob->gl_pathc; i++)
                free(pglob->gl_pathv[i]);
-       free(pglob->gl_pathv[i]);
+       free(pglob->gl_pathv);
 }
 
 static bool