]> Savannah Git Hosting - gnulib.git/commitdiff
utimensat: Fix test failures on macOS 10.13.
authorBruno Haible <bruno@clisp.org>
Sat, 2 Jan 2021 18:31:45 +0000 (19:31 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 2 Jan 2021 18:31:45 +0000 (19:31 +0100)
* lib/utimensat.c: Include <string.h>, <sys/stat.h>.
(rpl_utimensat): Check against invalid tv_nsec values. Before calling
utimensat, recognize a filename ending in a slash that does not point
to a directory.

ChangeLog
lib/utimensat.c

index fb6a8c2d9d68f957b9ac4a928ef1d712114d34af..183e8770338e3125ca1fbcc672ad18cec8a9ce96 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2021-01-02  Bruno Haible  <bruno@clisp.org>
+
+       utimensat: Fix test failures on macOS 10.13.
+       * lib/utimensat.c: Include <string.h>, <sys/stat.h>.
+       (rpl_utimensat): Check against invalid tv_nsec values. Before calling
+       utimensat, recognize a filename ending in a slash that does not point
+       to a directory.
+
 2021-01-02  Bruno Haible  <bruno@clisp.org>
 
        utimens: Fix test failure on macOS 10.13.
index 2cea64f6982b05a50e4d6252d456c98a6579e20b..1daff88e6e3fc52d54a1dec322b13600c9d53571 100644 (file)
@@ -24,6 +24,8 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
 
 #include "stat-time.h"
 #include "timespec.h"
@@ -105,6 +107,34 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
           return -1;
         }
 #  endif
+# endif
+# if defined __APPLE__ && defined __MACH__
+      /* macOS 10.13 does not reject invalid tv_nsec values either.  */
+      if (times
+          && ((times[0].tv_nsec != UTIME_OMIT
+               && times[0].tv_nsec != UTIME_NOW
+               && ! (0 <= times[0].tv_nsec
+                     && times[0].tv_nsec < TIMESPEC_HZ))
+              || (times[1].tv_nsec != UTIME_OMIT
+                  && times[1].tv_nsec != UTIME_NOW
+                  && ! (0 <= times[1].tv_nsec
+                        && times[1].tv_nsec < TIMESPEC_HZ))))
+        {
+          errno = EINVAL;
+          return -1;
+        }
+      size_t len = strlen (file);
+      if (len > 0 && file[len - 1] == '/')
+        {
+          struct stat statbuf;
+          if (fstatat (fd, file, &statbuf, 0) < 0)
+            return -1;
+          if (!S_ISDIR (statbuf.st_mode))
+            {
+              errno = ENOTDIR;
+              return -1;
+            }
+        }
 # endif
       result = utimensat (fd, file, times, flag);
       /* Linux kernel 2.6.25 has a bug where it returns EINVAL for