Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 magnus 1
Origin: http://repo.or.cz/w/libtar.git/commitdiff/e4c1f2974258d6a325622cfd712873d49b5e7a73
2
From: Chris Frey <cdfrey@foursquare.net>
3
Date: Thu, 24 Oct 2013 18:52:44 -0400
4
Subject: [PATCH] Change th_get_size() macro to return unsigned int
5
 
6
On systems where size_t is larger than an int (and larger than
7
unsigned int), then in various places in the library, where
8
stuff like this happens:
9
 
10
        size_t sz = th_get_size(t);
11
 
12
then the int value returned from th_get_size() is sign extended to
13
some unwieldy amount.
14
 
15
On 64bit systems, this can yield extremely large values.
16
 
17
By fixing this problem in the header, and only for th_get_size(),
18
we avoid breaking the API of the function call oct_to_int()
19
(which arguably should return an unsigned int, since the sscanf()
20
it uses expects to yield an unsigned int).  We also fix the library,
21
which uses th_get_size() internally to assign sizes to size_t.
22
 
23
The drawback is that not all client code that uses th_get_size()
24
will be fixed, until they recompile, but they will automatically
25
take advantage of the bugs fixed *inside* the library.
26
 
27
The remaining th_get_*() functions operate on modes and CRC values
28
and the like, and should be fine, remaining as ints.
29
 
30
Thanks very much to Magnus Holmgren for catching this behaviour.
31
https://lists.feep.net:8080/pipermail/libtar/2013-October/000365.html
32
---
33
 lib/libtar.h | 6 +++++-
34
 1 file changed, 5 insertions(+), 1 deletion(-)
35
 
36
diff --git a/lib/libtar.h b/lib/libtar.h
37
index 2fefee0..13bb82d 100644
38
--- a/lib/libtar.h
39
+++ b/lib/libtar.h
40
@@ -185,7 +185,11 @@ int th_write(TAR *t);
41
 
42
 /* decode tar header info */
43
 #define th_get_crc(t) oct_to_int((t)->th_buf.chksum)
44
-#define th_get_size(t) oct_to_int((t)->th_buf.size)
45
+/* We cast from int (what oct_to_int() returns) to
46
+   unsigned int, to avoid unwieldy sign extensions
47
+   from occurring on systems where size_t is bigger than int,
48
+   since th_get_size() is often stored into a size_t. */
49
+#define th_get_size(t) ((unsigned int)oct_to_int((t)->th_buf.size))
50
 #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime)
51
 #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor)
52
 #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor)