]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Make sure each delayed link entry is visited once
authorSergey Poznyakoff <gray@gnu.org>
Sat, 17 Jun 2023 08:16:12 +0000 (11:16 +0300)
committerSergey Poznyakoff <gray@gnu.org>
Sun, 18 Jun 2023 06:20:28 +0000 (09:20 +0300)
* src/extract.c (create_placeholder_file): Use FLEXNSIZEOF (overlooked
by c542d3d0c8)
(apply_delayed_links): Don't follow the "next" chain after its entries
have been applied.

src/extract.c

index 3bf407bc004773f8b89f92baf7111f7cdde4acde..030c0d4917a66dd3f3ed570c851a3b6d7015fe95 100644 (file)
@@ -1441,9 +1441,8 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made,
     {
       struct delayed_set_stat *h;
       struct delayed_link *p =
-       xmalloc (offsetof (struct delayed_link, target)
-                + strlen (current_stat_info.link_name)
-                + 1);
+       xmalloc (FLEXNSIZEOF (struct delayed_link, target,
+                             strlen (current_stat_info.link_name) + 1));
       if (prev)
        {
          p->next = prev->next;
@@ -1950,19 +1949,25 @@ apply_delayed_links (void)
   if (!delayed_link_table)
     return;
 
-  for (struct delayed_link *dl = hash_get_first (delayed_link_table);
-       dl;
-       dl = dl->next ? dl->next : hash_get_next (delayed_link_table, dl))
-    if (!dl->has_predecessor)
-      {
-       struct delayed_link *ds = dl;
-       do
-         {
-           apply_delayed_link (ds);
-           ds = ds->next;
-         }
-       while (ds);
-      }
+  for (struct delayed_link *dl = hash_get_first (delayed_link_table); dl;)
+    {
+      struct delayed_link *ds = dl;
+      if (!ds->has_predecessor)
+       {
+         do
+           {
+             apply_delayed_link (ds);
+             ds = ds->next;
+           }
+         while (ds);
+       }
+      else if (dl->next)
+       {
+         dl = dl->next;
+         continue;
+       }
+      dl = hash_get_next (delayed_link_table, dl);
+    }
 
   if (false)
     {