浏览代码

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 21 年之前
父节点
当前提交
8c0a6b24b2
共有 1 个文件被更改,包括 18 次插入19 次删除
  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);