Rev 33 | Details | Compare with Previous | 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) |