]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
test: make Windows file assertions act like lstat 3220/head
authorDustin L. Howett <dustin@howett.net>
Wed, 1 Jul 2026 17:24:09 +0000 (12:24 -0500)
committerDustin L. Howett <dustin@howett.net>
Tue, 7 Jul 2026 15:24:00 +0000 (10:24 -0500)
I've removed our lstat shim and replaced all uses with my_GetFileInformationByName.

test_utils/test_main.c

index a8d84f3ccba3a4fd2c58028b2242b4e209ca2921..3238feed46c75705b34eafed0195096296a23167 100644 (file)
@@ -153,9 +153,6 @@ extern char **environ;
 #if !defined(__BORLANDC__)
 #define getcwd _getcwd
 #endif
-#define lstat stat
-/*#define lstat _stat64*/
-/*#define stat _stat64*/
 #define rmdir _rmdir
 #if !defined(__BORLANDC__)
 #define strdup _strdup
@@ -358,10 +355,28 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
 {
        HANDLE h;
        int r;
+       const char *p;
+       char *s, *pn;
+
+       /* Replace slashes with backslashes in path */
+       pn = malloc(strlen(path) + 1);
+       if (pn == NULL) {
+               return (0);
+       }
+
+       for (p = path, s = pn; *p != '\0'; p++, s++) {
+               if (*p == '/')
+                       *s = '\\';
+               else
+                       *s = *p;
+       }
+       *s = '\0';
 
        memset(bhfi, 0, sizeof(*bhfi));
-       h = CreateFileA(path, FILE_READ_ATTRIBUTES, 0, NULL,
-               OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+       h = CreateFileA(pn, FILE_READ_ATTRIBUTES, 0, NULL,
+               OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS |
+                   FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+       free(pn);
        if (h == INVALID_HANDLE_VALUE)
                return (0);
        r = GetFileInformationByHandle(h, bhfi);
@@ -1508,7 +1523,8 @@ assertion_file_time(const char *file, int line,
         * a directory file. If not, CreateFile() will fail when
         * the pathname is a directory. */
        h = CreateFileA(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
-           OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+           OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS |
+               FILE_FLAG_OPEN_REPARSE_POINT, NULL);
        if (h == INVALID_HANDLE_VALUE) {
                failure_start(file, line, "Can't access %s\n", pathname);
                failure_finish(NULL);
@@ -1733,13 +1749,28 @@ assertion_file_size(const char *file, int line, const char *pathname, long size)
 int
 assertion_is_dir(const char *file, int line, const char *pathname, int mode)
 {
-       struct stat st;
        int r;
 
+       assertion_count(file, line);
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
+       BY_HANDLE_FILE_INFORMATION st;
        (void)mode; /* UNUSED */
-#endif
-       assertion_count(file, line);
+       r = my_GetFileInformationByName(pathname, &st);
+       if (r == 0) {
+               failure_start(file, line, "Dir should exist: %s", pathname);
+               failure_finish(NULL);
+               return (0);
+       }
+       if ((st.dwFileAttributes &
+           (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) !=
+           FILE_ATTRIBUTE_DIRECTORY) {
+               failure_start(file, line, "%s is not a dir", pathname);
+               failure_finish(NULL);
+               return (0);
+       }
+#else
+       struct stat st;
        r = lstat(pathname, &st);
        if (r != 0) {
                failure_start(file, line, "Dir should exist: %s", pathname);
@@ -1751,7 +1782,6 @@ assertion_is_dir(const char *file, int line, const char *pathname, int mode)
                failure_finish(NULL);
                return (0);
        }
-#if !defined(_WIN32) || defined(__CYGWIN__)
        /* Windows doesn't handle permissions the same way as POSIX,
         * so just ignore the mode tests. */
        /* TODO: Can we do better here? */
@@ -1771,20 +1801,35 @@ assertion_is_dir(const char *file, int line, const char *pathname, int mode)
 int
 assertion_is_reg(const char *file, int line, const char *pathname, int mode)
 {
-       struct stat st;
        int r;
 
+       assertion_count(file, line);
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
+       BY_HANDLE_FILE_INFORMATION st;
        (void)mode; /* UNUSED */
-#endif
-       assertion_count(file, line);
+       r = my_GetFileInformationByName(pathname, &st);
+       if (r == 0) {
+               failure_start(file, line, "File should exist: %s", pathname);
+               failure_finish(NULL);
+               return (0);
+       }
+       if ((st.dwFileAttributes &
+           (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) !=
+           0) {
+               failure_start(file, line, "%s is not a regular file", pathname);
+               failure_finish(NULL);
+               return (0);
+       }
+#else
+       struct stat st;
        r = lstat(pathname, &st);
        if (r != 0 || !S_ISREG(st.st_mode)) {
                failure_start(file, line, "File should exist: %s", pathname);
                failure_finish(NULL);
                return (0);
        }
-#if !defined(_WIN32) || defined(__CYGWIN__)
+
        /* Windows doesn't handle permissions the same way as POSIX,
         * so just ignore the mode tests. */
        /* TODO: Can we do better here? */
@@ -2160,7 +2205,7 @@ assertion_utimes(const char *file, int line, const char *pathname,
        assertion_count(file, line);
        h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
-                   FILE_FLAG_BACKUP_SEMANTICS, NULL);
+                   FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
        if (h == INVALID_HANDLE_VALUE) {
                failure_start(file, line, "Can't access %s\n", pathname);
                failure_finish(NULL);