--- tar-1.22/src/incremen.c 2008-12-29 18:18:00.000000000 -0500 +++ tar-1.22patched/src/incremen.c 2009-03-23 16:41:44.262611461 -0400 @@ -1073,7 +1073,9 @@ errno = 0; *pval = strtoimax (buf, &ep, 10); if (c || errno || *pval < min_val) - FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file"))); + FATAL_ERROR ((0, errno, + _("Unexpected field value in snapshot file: \"%s\""), + buf)); } /* Read from file FP a nul-terminated string and convert it to @@ -1113,7 +1115,9 @@ errno = 0; *pval = strtoumax (buf, &ep, 10); if (c || errno || max_val < *pval) - FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file"))); + FATAL_ERROR ((0, errno, + _("Unexpected field value in snapshot file: \"%s\""), + buf)); return c; } @@ -1293,6 +1297,30 @@ free (buf); } +/* Write a timespec out to the snapshot file, issuing a warning if + the values are out of range (i.e. if they would cause an error + when the file is being parsed by read_timespec() ). +*/ +void +write_timespec (FILE *fp, struct timespec ts, const char *dirname ) +{ + char buf[UINTMAX_STRSIZE_BOUND]; + char *s; + + s = (TYPE_SIGNED (time_t) + ? imaxtostr (ts.tv_sec, buf) + : umaxtostr (ts.tv_sec, buf)); + fwrite (s, strlen (s) + 1, 1, fp); + s = umaxtostr (ts.tv_nsec, buf); + /* depending on the data type of tv_nsec, an invalid value could + appear to be negative or too large; either case is an error. */ + if (ts.tv_nsec < 0 || ts.tv_nsec > BILLION -1) + WARN ((0, 0, + _("Invalid timestamp nsec value \"%s\" found for entry \"%s\""), + s, dirname)); + fwrite (s, strlen (s) + 1, 1, fp); +} + /* Output incremental data for the directory ENTRY to the file DATA. Return nonzero if successful, preserving errno on write failure. */ static bool @@ -1308,12 +1336,7 @@ s = DIR_IS_NFS (directory) ? "1" : "0"; fwrite (s, 2, 1, fp); - s = (TYPE_SIGNED (time_t) - ? imaxtostr (directory->mtime.tv_sec, buf) - : umaxtostr (directory->mtime.tv_sec, buf)); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (directory->mtime.tv_nsec, buf); - fwrite (s, strlen (s) + 1, 1, fp); + write_timespec(fp, directory->mtime, directory->name); s = umaxtostr (directory->device_number, buf); fwrite (s, strlen (s) + 1, 1, fp); s = umaxtostr (directory->inode_number, buf); @@ -1341,8 +1364,6 @@ write_directory_file (void) { FILE *fp = listed_incremental_stream; - char buf[UINTMAX_STRSIZE_BOUND]; - char *s; if (! fp) return; @@ -1355,12 +1376,7 @@ fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION, TAR_INCREMENTAL_VERSION); - s = (TYPE_SIGNED (time_t) - ? imaxtostr (start_time.tv_sec, buf) - : umaxtostr (start_time.tv_sec, buf)); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (start_time.tv_nsec, buf); - fwrite (s, strlen (s) + 1, 1, fp); + write_timespec(fp, start_time, "tar execution start_time"); if (! ferror (fp) && directory_table) hash_do_for_each (directory_table, write_directory_file_entry, fp);