Commit 1d4ddb8ecf308b8b913dfbc5d6abb9996779808c

Edward Thomson 2019-01-20T23:42:08

iterator: cast filesystem iterator entry values explicitly The filesystem iterator takes `stat` data from disk and puts them into index entries, which use 32 bit ints for time (the seconds portion) and filesize. However, on most systems these are not 32 bit, thus will typically invoke a warning. Most users ignore these fields entirely. Diff and checkout code do use the values, however only for the cache to determine if they should check file modification. Thus, this is not a critical error (and will cause a hash recomputation at worst).

diff --git a/src/iterator.c b/src/iterator.c
index 90bbb81..0db9292 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1485,8 +1485,15 @@ static void filesystem_iterator_set_current(
 	filesystem_iterator *iter,
 	filesystem_iterator_entry *entry)
 {
-	iter->entry.ctime.seconds = entry->st.st_ctime;
-	iter->entry.mtime.seconds = entry->st.st_mtime;
+	/*
+	 * Index entries are limited to 32 bit timestamps.  We can safely
+	 * cast this since workdir times are only used in the cache; any
+	 * mismatch will cause a hash recomputation which is unfortunate
+	 * but affects only people who set their filetimes to 2038.
+	 * (Same with the file size.)
+	 */
+	iter->entry.ctime.seconds = (int32_t)entry->st.st_ctime;
+	iter->entry.mtime.seconds = (int32_t)entry->st.st_mtime;
 
 #if defined(GIT_USE_NSEC)
 	iter->entry.ctime.nanoseconds = entry->st.st_ctime_nsec;
@@ -1501,7 +1508,7 @@ static void filesystem_iterator_set_current(
 	iter->entry.mode = git_futils_canonical_mode(entry->st.st_mode);
 	iter->entry.uid = entry->st.st_uid;
 	iter->entry.gid = entry->st.st_gid;
-	iter->entry.file_size = entry->st.st_size;
+	iter->entry.file_size = (uint32_t)entry->st.st_size;
 
 	if (iter->base.flags & GIT_ITERATOR_INCLUDE_HASH)
 		git_oid_cpy(&iter->entry.id, &entry->id);