3 #include "delta-apply.h"
6 * This file was heavily cribbed from BinaryDelta.java in JGit, which
7 * itself was heavily cribbed from <code>patch-delta.c</code> in the
8 * GIT project. The original delta patching code was written by
9 * Nicolas Pitre <nico@cam.org>.
13 const unsigned char **delta
,
14 const unsigned char *end
)
16 const unsigned char *d
= *delta
;
18 unsigned int c
, shift
= 0;
24 r
|= (c
& 0x7f) << shift
;
33 const unsigned char *base
,
35 const unsigned char *delta
,
38 const unsigned char *delta_end
= delta
+ delta_len
;
40 unsigned char *res_dp
;
42 /* Check that the base size matches the data we were given;
43 * if not we would underflow while accessing data from the
44 * base object, resulting in data corruption or segfault.
46 if (base_len
!= hdr_sz(&delta
, delta_end
))
49 res_sz
= hdr_sz(&delta
, delta_end
);
50 if ((res_dp
= git__malloc(res_sz
+ 1)) == NULL
)
52 res_dp
[res_sz
] = '\0';
56 while (delta
< delta_end
) {
57 unsigned char cmd
= *delta
++;
59 /* cmd is a copy instruction; copy from the base.
61 size_t off
= 0, len
= 0;
63 if (cmd
& 0x01) off
= *delta
++;
64 if (cmd
& 0x02) off
|= *delta
++ << 8;
65 if (cmd
& 0x04) off
|= *delta
++ << 16;
66 if (cmd
& 0x08) off
|= *delta
++ << 24;
68 if (cmd
& 0x10) len
= *delta
++;
69 if (cmd
& 0x20) len
|= *delta
++ << 8;
70 if (cmd
& 0x40) len
|= *delta
++ << 16;
71 if (!len
) len
= 0x10000;
73 if (base_len
< off
+ len
|| res_sz
< len
)
75 memcpy(res_dp
, base
+ off
, len
);
80 /* cmd is a literal insert instruction; copy from
81 * the delta stream itself.
83 if (delta_end
- delta
< cmd
|| res_sz
< cmd
)
85 memcpy(res_dp
, delta
, cmd
);
91 /* cmd == 0 is reserved for future encodings.
97 if (delta
!= delta_end
|| res_sz
)