|
|
@@ -40,13 +40,20 @@ void *patch_delta(const void *src_buf, unsigned long src_size, |
|
|
|
cmd = *data++; |
|
|
|
if (cmd & 0x80) { |
|
|
|
unsigned long cp_off = 0, cp_size = 0; |
|
|
|
if (cmd & 0x01) cp_off = *data++; |
|
|
|
if (cmd & 0x02) cp_off |= (*data++ << 8); |
|
|
|
if (cmd & 0x04) cp_off |= (*data++ << 16); |
|
|
|
if (cmd & 0x08) cp_off |= ((unsigned) *data++ << 24); |
|
|
|
if (cmd & 0x10) cp_size = *data++; |
|
|
|
if (cmd & 0x20) cp_size |= (*data++ << 8); |
|
|
|
if (cmd & 0x40) cp_size |= (*data++ << 16); |
|
|
|
#define PARSE_CP_PARAM(bit, var, shift) do { \ |
|
|
|
if (cmd & (bit)) { \ |
|
|
|
if (data >= top) \ |
|
|
|
goto bad_length; \ |
|
|
|
var |= ((unsigned) *data++ << (shift)); \ |
|
|
|
} } while (0) |
|
|
|
PARSE_CP_PARAM(0x01, cp_off, 0); |
|
|
|
PARSE_CP_PARAM(0x02, cp_off, 8); |
|
|
|
PARSE_CP_PARAM(0x04, cp_off, 16); |
|
|
|
PARSE_CP_PARAM(0x08, cp_off, 24); |
|
|
|
PARSE_CP_PARAM(0x10, cp_size, 0); |
|
|
|
PARSE_CP_PARAM(0x20, cp_size, 8); |
|
|
|
PARSE_CP_PARAM(0x40, cp_size, 16); |
|
|
|
#undef PARSE_CP_PARAM |
|
|
|
if (cp_size == 0) cp_size = 0x10000; |
|
|
|
if (unsigned_add_overflows(cp_off, cp_size) || |
|
|
|
cp_off + cp_size > src_size || |
|
|
|