]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Save a syscall in trivial extract_dir
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 22 Jul 2026 23:37:35 +0000 (16:37 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 30 Jul 2026 06:12:46 +0000 (23:12 -0700)
* src/extract.c (trivial_base_name): New function.
(extract_dir): Use it.

src/extract.c

index b79b61a9bd40d1334d70388b5839e1ca9747e5c2..5febf6de6faf60ca0f0ce4fb8f4e399d8ed01112 100644 (file)
@@ -1176,6 +1176,19 @@ safe_dir_mode (struct stat const *st)
          | (we_are_root ? 0 : MODE_WXUSR));
 }
 
+
+/* Return true if the base name BASE returned by fdbase corresponds to
+   a file that trivially exists.  This is true if BASE is the empty
+   string (which means the original name is a file system root); or if
+   BASE is "." or "..", possibly followed by slashes.  */
+static bool
+trivial_base_name (char const *base)
+{
+  bool dotted = base[0] == '.';
+  char const *p = base + dotted + (dotted & (base[dotted] == '.'));
+  return !*p | ISSLASH (*p);
+}
+
 /* Extractor functions for various member types */
 
 static bool
@@ -1210,7 +1223,17 @@ extract_dir (char *file_name, char UNNAMED (typeflag))
   for (;;)
     {
       struct fdbase f = fdbase (file_name);
-      status = f.fd == BADFD ? -1 : mkdirat (f.fd, f.base, mode);
+      if (f.fd == BADFD)
+       status = -1;
+      else if (trivial_base_name (f.base))
+       {
+         /* Save a syscall.  */
+         errno = EEXIST;
+         status = -1;
+       }
+      else
+       status = mkdirat (f.fd, f.base, mode);
+
       if (status == 0)
        {
          current_mode = mode & ~ current_umask;