cpio.c: fixed the integer conversion involving cpio file size

The code in question uses an improvised "strntoul" function (hidden
behind the GET_NUM_FIELD macro) which returns "int".

int cpioHeaderRead(FSM_t fsm, struct stat * st)
...
    GET_NUM_FIELD(hdr.filesize, st->st_size);

When a file size undergoes an "int bottleneck", it cannot be safely
converted back to an unsigned 64-bit integer.  By the C rules, if the
size is in the range 2G..4G-1, int becomes negative (or this may be
undefined behaviour already, I'm not a language lawyer), and conversion
to unsigned 64-bit is performed as if by adding 2^64 to the negative
value.

So you get a huge 64-bit file size.  Funnily enough, if you truncate it
to 32 bits, it's back to normal!  That's why things worked with 32-bit
size_t.

static int expandRegular(/*@special@*/ FSM_t fsm)
...
    size_t left = st->st_size;
This commit is contained in:
Alexey Tourbin 2018-06-30 02:47:46 +03:00
parent 5c202f0b50
commit 3d9823b9a4

View File

@ -27,7 +27,7 @@ extern int _fsm_debug;
* @param num max no. of bytes to read
* @return converted integer
*/
static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
static unsigned long strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
/*@modifies *endptr @*/
{
char * buf, * end;