Cast 64 bit off_t to 32 bit size_t

Some systems have sizeof(off_t) == 8 while sizeof(size_t) == 4.
This implies that we are able to access and work on files whose
maximum length is around 2^63-1 bytes, but we can only malloc or
mmap somewhat less than 2^32-1 bytes of memory.

On such a system an implicit conversion of off_t to size_t can cause
the size_t to wrap, resulting in unexpected and exciting behavior.
Right now we are working around all gcc warnings generated by the
-Wshorten-64-to-32 option by passing the off_t through xsize_t().

In the future we should make xsize_t on such problematic platforms
detect the wrapping and die if such a file is accessed.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
diff --git a/diff.c b/diff.c
index e225de2..8f7a7d1 100644
--- a/diff.c
+++ b/diff.c
@@ -1399,7 +1399,7 @@
 				return err;
 			}
 		}
-		s->size = st.st_size;
+		s->size = xsize_t(st.st_size);
 		if (!s->size)
 			goto empty;
 		if (size_only)
@@ -1515,12 +1515,13 @@
 		if (S_ISLNK(st.st_mode)) {
 			int ret;
 			char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */
+			size_t sz = xsize_t(st.st_size);
 			if (sizeof(buf) <= st.st_size)
 				die("symlink too long: %s", name);
-			ret = readlink(name, buf, st.st_size);
+			ret = readlink(name, buf, sz);
 			if (ret < 0)
 				die("readlink(%s)", name);
-			prep_temp_blob(temp, buf, st.st_size,
+			prep_temp_blob(temp, buf, sz,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
 				       (one->sha1_valid ?
@@ -2138,7 +2139,7 @@
 	/* user says num divided by scale and we say internally that
 	 * is MAX_SCORE * num / scale.
 	 */
-	return (num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale);
+	return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale));
 }
 
 int diff_scoreopt_parse(const char *opt)