]> Dogcows Code - chaz/tar/blobdiff - src/create.c
Do not zero-terminate name field if
[chaz/tar] / src / create.c
index b3e4d73e9d172fb7c1dd4fe71addaef359db181f..9164ab9bbda6c5412476dd677771a22225da4f9c 100644 (file)
@@ -353,6 +353,15 @@ write_eot (void)
   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 */
 static union block *
 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));
 
-  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);
 
   time (&t);
@@ -386,9 +394,7 @@ write_short_name (struct tar_stat_info *st)
 {
   union block *header = find_next_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;
 }
 
@@ -451,7 +457,7 @@ write_ustar_long_name (const char *name)
     }
   
   i = split_long_name (name, length);
-  if (i == 0)
+  if (i == 0 || length - i -1 > NAME_FIELD_SIZE)
     {
       WARN ((0, 0,
             _("%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 ();
   memset (header->buffer, 0, sizeof (header->buffer));
   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;
 }
@@ -570,7 +576,7 @@ write_extended (union block *old_header, char type)
 static union block * 
 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);
   else
     return write_short_name (st);
@@ -588,8 +594,6 @@ start_header (const char *name, struct tar_stat_info *st)
   union block *header;
 
   name = safer_name_suffix (name, 0);
-  if (name[0] == '.' && name[1] == 0) /*FIXME!!!*/
-    return NULL;
   assign_string (&st->file_name, name);
 
   header = write_header_name (st);
@@ -1217,15 +1221,6 @@ dump_file (char *p, int top_level, dev_t parent_device)
          block_ordinal = current_block_ordinal ();
          current_stat_info.stat.st_size = 0;   /* force 0 size on dir */
 
-         /* FIXME: If people could really read standard archives, this
-            should be:
-
-            header
-              = start_header (standard_option ? p : namebuf, &current_stat_info);
-
-            but since they'd interpret DIRTYPE blocks as regular
-            files, we'd better put the / on the name.  */
-
          header = start_header (namebuf, &current_stat_info);
          if (!header)
            return;
@@ -1358,17 +1353,15 @@ dump_file (char *p, int top_level, dev_t parent_device)
              
              block_ordinal = current_block_ordinal ();
              assign_string (&current_stat_info.link_name, link_name);
-             if (NAME_FIELD_SIZE <= strlen (link_name))
+             if (NAME_FIELD_SIZE < strlen (link_name))
                write_long_link (&current_stat_info);
 
              current_stat_info.stat.st_size = 0;
              header = start_header (p, &current_stat_info);
              if (!header)
                return;
-             strncpy (header->header.linkname, link_name, NAME_FIELD_SIZE);
-
-             /* Force null termination.  */
-             header->header.linkname[NAME_FIELD_SIZE - 1] = 0;
+             tar_copy_str (header->header.linkname, link_name,
+                           NAME_FIELD_SIZE);
 
              header->header.typeflag = LNKTYPE;
              finish_header (header, block_ordinal);
@@ -1487,8 +1480,8 @@ dump_file (char *p, int top_level, dev_t parent_device)
 
          sizeleft = current_stat_info.stat.st_size;
 
-         /* Don't bother opening empty, world readable files.  Also do not open
-            files when archive is meant for /dev/null.  */
+         /* Don't bother opening empty, world readable files.  Also do not
+            open files when archive is meant for /dev/null.  */
 
          if (dev_null_output
              || (sizeleft == 0
@@ -1528,8 +1521,7 @@ dump_file (char *p, int top_level, dev_t parent_device)
            isextended = header->oldgnu_header.isextended;
          else
            isextended = 0;
-         if (isextended)
-           abort();
+
          save_typeflag = header->header.typeflag;
          finish_header (header, block_ordinal);
          if (isextended)
@@ -1699,7 +1691,7 @@ dump_file (char *p, int top_level, dev_t parent_device)
            }
          buffer[size] = '\0';
          assign_string (&current_stat_info.link_name, buffer);
-         if (size >= NAME_FIELD_SIZE)
+         if (size > NAME_FIELD_SIZE)
            write_long_link (&current_stat_info);
 
          block_ordinal = current_block_ordinal ();
@@ -1707,8 +1699,7 @@ dump_file (char *p, int top_level, dev_t parent_device)
          header = start_header (p, &current_stat_info);
          if (!header)
            return;
-         strncpy (header->header.linkname, buffer, NAME_FIELD_SIZE);
-         header->header.linkname[NAME_FIELD_SIZE - 1] = '\0';
+         tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
          header->header.typeflag = SYMTYPE;
          finish_header (header, block_ordinal);
          /* nothing more to do to it */
@@ -1753,8 +1744,10 @@ dump_file (char *p, int top_level, dev_t parent_device)
 
   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);
This page took 0.029076 seconds and 4 git commands to generate.