sha1_file: don't convert off_t to size_t too early to avoid potential die()

xsize_t() checks if an off_t argument can be safely converted to a size_t return value. If the check is executed too early, it could fail for large files on 32-bit architectures even if the size_t code path is not taken. Other paths might be able to handle the large file. Specifically, index_stream_convert_blob() is able to handle a large file if a filter is configured that returns a small result. Signed-off-by: Steffen Prohaska <prohaska@zib.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Steffen Prohaska committed Sep 21, 2014 at 12:03 UTC 9079ab7cb6768fa04e086303f90be043b423cca4
1 file changed +9 -4
sha1_file.c
+9 -4
@@ -3178,17 +3178,22 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st,
3178 enum object_type type, const char *path, unsigned flags)
3179 {
3180 int ret;
3181 - size_t size = xsize_t(st->st_size);
3181
3182 + /*
3183 + * Call xsize_t() only when needed to avoid potentially unnecessary
3184 + * die() for large files.
3185 + */
3186 if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(path))
3187 ret = index_stream_convert_blob(sha1, fd, path, flags);
3188 else if (!S_ISREG(st->st_mode))
3189 ret = index_pipe(sha1, fd, type, path, flags);
3187 - else if (size <= big_file_threshold || type != OBJ_BLOB ||
3190 + else if (st->st_size <= big_file_threshold || type != OBJ_BLOB ||
3191 (path && would_convert_to_git(path)))
3189 - ret = index_core(sha1, fd, size, type, path, flags);
3192 + ret = index_core(sha1, fd, xsize_t(st->st_size), type, path,
3193 + flags);
3194 else
3191 - ret = index_stream(sha1, fd, size, type, path, flags);
3195 + ret = index_stream(sha1, fd, xsize_t(st->st_size), type, path,
3196 + flags);
3197 close(fd);
3198 return ret;
3199 }