Browse Source

Do not zero-terminate name field if
the name is exactly 100 characters long.
(write_ustar_long_name): Fixed cheking for unsplittable
names.

Sergey Poznyakoff 22 years ago
parent
commit
8c0a6b24b2
1 changed files with 18 additions and 19 deletions
  1. 18 19
      src/create.c

+ 18 - 19
src/create.c

@@ -353,6 +353,15 @@ write_eot (void)
   set_next_block_after (pointer);
   set_next_block_after (pointer);
 }
 }
 
 
+/* Copy at most LEN bytes from SRC to DST. Terminate with NUL unless
+   SRC is LEN characters long */
+static void
+tar_copy_str (char *dst, const char *src, size_t len)
+{
+  dst[len-1] = 0;
+  strncpy (dst, src, len);
+}
+
 /* Write a "private" header */
 /* Write a "private" header */
 static union block *
 static union block *
 start_private_header (const char *name, size_t size)
 start_private_header (const char *name, size_t size)
@@ -362,8 +371,7 @@ start_private_header (const char *name, size_t size)
   
   
   memset (header->buffer, 0, sizeof (union block));
   memset (header->buffer, 0, sizeof (union block));
 
 
-  strncpy (header->header.name, name, NAME_FIELD_SIZE);
-  header->header.name[NAME_FIELD_SIZE - 1] = '\0';
+  tar_copy_str (header->header.name, name, NAME_FIELD_SIZE);
   OFF_TO_CHARS (size, header->header.size);
   OFF_TO_CHARS (size, header->header.size);
 
 
   time (&t);
   time (&t);
@@ -386,9 +394,7 @@ write_short_name (struct tar_stat_info *st)
 {
 {
   union block *header = find_next_block ();
   union block *header = find_next_block ();
   memset (header->buffer, 0, sizeof (union block));
   memset (header->buffer, 0, sizeof (union block));
-  
-  strncpy (header->header.name, st->file_name, NAME_FIELD_SIZE);
-  header->header.name[NAME_FIELD_SIZE - 1] = '\0';
+  tar_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);
   return header;
   return header;
 }
 }
 
 
@@ -451,7 +457,7 @@ write_ustar_long_name (const char *name)
     }
     }
   
   
   i = split_long_name (name, length);
   i = split_long_name (name, length);
-  if (i == 0)
+  if (i == 0 || length - i -1 > NAME_FIELD_SIZE)
     {
     {
       WARN ((0, 0,
       WARN ((0, 0,
 	     _("%s: file name is too long (cannot be split); not dumped"),
 	     _("%s: file name is too long (cannot be split); not dumped"),
@@ -463,7 +469,7 @@ write_ustar_long_name (const char *name)
   header = find_next_block ();
   header = find_next_block ();
   memset (header->buffer, 0, sizeof (header->buffer));
   memset (header->buffer, 0, sizeof (header->buffer));
   memcpy (header->header.prefix, name, i);
   memcpy (header->header.prefix, name, i);
-  memcpy (header->header.name, name + i + 1, length - i);
+  memcpy (header->header.name, name + i + 1, length - i - 1);
   
   
   return header;
   return header;
 }
 }
@@ -570,7 +576,7 @@ write_extended (union block *old_header, char type)
 static union block * 
 static union block * 
 write_header_name (struct tar_stat_info *st)
 write_header_name (struct tar_stat_info *st)
 {
 {
-  if (NAME_FIELD_SIZE <= strlen (st->file_name))
+  if (NAME_FIELD_SIZE < strlen (st->file_name))
     return write_long_name (st);
     return write_long_name (st);
   else
   else
     return write_short_name (st);
     return write_short_name (st);
@@ -1085,15 +1091,6 @@ compare_links (void const *entry1, void const *entry2)
   return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
   return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
 }
 }
 
 
-/* Copy at most LEN bytes from SRC to DST. Terminate with NUL unless
-   SRC is LEN characters long */
-static void
-tar_copy_str (char *dst, const char *src, size_t len)
-{
-  dst[len-1] = 0;
-  strncpy (dst, src, len);
-}
-
 /* Table of all non-directories that we've written so far.  Any time
 /* Table of all non-directories that we've written so far.  Any time
    we see another, we check the table and avoid dumping the data
    we see another, we check the table and avoid dumping the data
    again if we've done it once already.  */
    again if we've done it once already.  */
@@ -1747,8 +1744,10 @@ dump_file (char *p, int top_level, dev_t parent_device)
 
 
   if (type != FIFOTYPE)
   if (type != FIFOTYPE)
     {
     {
-      MAJOR_TO_CHARS (major (current_stat_info.stat.st_rdev), header->header.devmajor);
-      MINOR_TO_CHARS (minor (current_stat_info.stat.st_rdev), header->header.devminor);
+      MAJOR_TO_CHARS (major (current_stat_info.stat.st_rdev),
+		      header->header.devmajor);
+      MINOR_TO_CHARS (minor (current_stat_info.stat.st_rdev),
+		      header->header.devminor);
     }
     }
 
 
   finish_header (header, block_ordinal);
   finish_header (header, block_ordinal);