@@ -109,6 +109,13 @@ static int max_change, max_len;
109
109
*/
110
110
static int linenr = 1 ;
111
111
112
+ /*
113
+ * This represents one "hunk" from a patch, starting with
114
+ * "@@ -oldpos,oldlines +newpos,newlines @@" marker. The
115
+ * patch text is pointed at by patch, and its byte length
116
+ * is stored in size. leading and trailing are the number
117
+ * of context lines.
118
+ */
112
119
struct fragment {
113
120
unsigned long leading , trailing ;
114
121
unsigned long oldpos , oldlines ;
@@ -118,12 +125,19 @@ struct fragment {
118
125
struct fragment * next ;
119
126
};
120
127
128
+ /*
129
+ * When dealing with a binary patch, we reuse "leading" field
130
+ * to store the type of the binary hunk, either deflated "delta"
131
+ * or deflated "literal".
132
+ */
133
+ #define binary_patch_method leading
134
+ #define BINARY_DELTA_DEFLATED 1
135
+ #define BINARY_LITERAL_DEFLATED 2
136
+
121
137
struct patch {
122
138
char * new_name , * old_name , * def_name ;
123
139
unsigned int old_mode , new_mode ;
124
140
int is_rename , is_copy , is_new , is_delete , is_binary ;
125
- #define BINARY_DELTA_DEFLATED 1
126
- #define BINARY_LITERAL_DEFLATED 2
127
141
unsigned long deflate_origlen ;
128
142
int lines_added , lines_deleted ;
129
143
int score ;
@@ -979,43 +993,70 @@ static inline int metadata_changes(struct patch *patch)
979
993
patch -> old_mode != patch -> new_mode );
980
994
}
981
995
982
- static int parse_binary (char * buffer , unsigned long size , struct patch * patch )
996
+ static char * inflate_it (const void * data , unsigned long size ,
997
+ unsigned long inflated_size )
983
998
{
984
- /* We have read "GIT binary patch\n"; what follows is a line
985
- * that says the patch method (currently, either "deflated
986
- * literal" or "deflated delta") and the length of data before
987
- * deflating; a sequence of 'length-byte' followed by base-85
988
- * encoded data follows.
999
+ z_stream stream ;
1000
+ void * out ;
1001
+ int st ;
1002
+
1003
+ memset (& stream , 0 , sizeof (stream ));
1004
+
1005
+ stream .next_in = (unsigned char * )data ;
1006
+ stream .avail_in = size ;
1007
+ stream .next_out = out = xmalloc (inflated_size );
1008
+ stream .avail_out = inflated_size ;
1009
+ inflateInit (& stream );
1010
+ st = inflate (& stream , Z_FINISH );
1011
+ if ((st != Z_STREAM_END ) || stream .total_out != inflated_size ) {
1012
+ free (out );
1013
+ return NULL ;
1014
+ }
1015
+ return out ;
1016
+ }
1017
+
1018
+ static struct fragment * parse_binary_hunk (char * * buf_p ,
1019
+ unsigned long * sz_p ,
1020
+ int * status_p ,
1021
+ int * used_p )
1022
+ {
1023
+ /* Expect a line that begins with binary patch method ("literal"
1024
+ * or "delta"), followed by the length of data before deflating.
1025
+ * a sequence of 'length-byte' followed by base-85 encoded data
1026
+ * should follow, terminated by a newline.
989
1027
*
990
1028
* Each 5-byte sequence of base-85 encodes up to 4 bytes,
991
1029
* and we would limit the patch line to 66 characters,
992
1030
* so one line can fit up to 13 groups that would decode
993
1031
* to 52 bytes max. The length byte 'A'-'Z' corresponds
994
1032
* to 1-26 bytes, and 'a'-'z' corresponds to 27-52 bytes.
995
- * The end of binary is signaled with an empty line.
996
1033
*/
997
1034
int llen , used ;
998
- struct fragment * fragment ;
1035
+ unsigned long size = * sz_p ;
1036
+ char * buffer = * buf_p ;
1037
+ int patch_method ;
1038
+ unsigned long origlen ;
999
1039
char * data = NULL ;
1040
+ int hunk_size = 0 ;
1041
+ struct fragment * frag ;
1000
1042
1001
- patch -> fragments = fragment = xcalloc (1 , sizeof (* fragment ));
1002
-
1003
- /* Grab the type of patch */
1004
1043
llen = linelen (buffer , size );
1005
1044
used = llen ;
1006
- linenr ++ ;
1045
+
1046
+ * status_p = 0 ;
1007
1047
1008
1048
if (!strncmp (buffer , "delta " , 6 )) {
1009
- patch -> is_binary = BINARY_DELTA_DEFLATED ;
1010
- patch -> deflate_origlen = strtoul (buffer + 6 , NULL , 10 );
1049
+ patch_method = BINARY_DELTA_DEFLATED ;
1050
+ origlen = strtoul (buffer + 6 , NULL , 10 );
1011
1051
}
1012
1052
else if (!strncmp (buffer , "literal " , 8 )) {
1013
- patch -> is_binary = BINARY_LITERAL_DEFLATED ;
1014
- patch -> deflate_origlen = strtoul (buffer + 8 , NULL , 10 );
1053
+ patch_method = BINARY_LITERAL_DEFLATED ;
1054
+ origlen = strtoul (buffer + 8 , NULL , 10 );
1015
1055
}
1016
1056
else
1017
- return error ("unrecognized binary patch at line %d: %.*s" ,
1018
- linenr - 1 , llen - 1 , buffer );
1057
+ return NULL ;
1058
+
1059
+ linenr ++ ;
1019
1060
buffer += llen ;
1020
1061
while (1 ) {
1021
1062
int byte_length , max_byte_length , newsize ;
@@ -1044,21 +1085,79 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
1044
1085
if (max_byte_length < byte_length ||
1045
1086
byte_length <= max_byte_length - 4 )
1046
1087
goto corrupt ;
1047
- newsize = fragment -> size + byte_length ;
1088
+ newsize = hunk_size + byte_length ;
1048
1089
data = xrealloc (data , newsize );
1049
- if (decode_85 (data + fragment -> size ,
1050
- buffer + 1 ,
1051
- byte_length ))
1090
+ if (decode_85 (data + hunk_size , buffer + 1 , byte_length ))
1052
1091
goto corrupt ;
1053
- fragment -> size = newsize ;
1092
+ hunk_size = newsize ;
1054
1093
buffer += llen ;
1055
1094
size -= llen ;
1056
1095
}
1057
- fragment -> patch = data ;
1058
- return used ;
1096
+
1097
+ frag = xcalloc (1 , sizeof (* frag ));
1098
+ frag -> patch = inflate_it (data , hunk_size , origlen );
1099
+ if (!frag -> patch )
1100
+ goto corrupt ;
1101
+ free (data );
1102
+ frag -> size = origlen ;
1103
+ * buf_p = buffer ;
1104
+ * sz_p = size ;
1105
+ * used_p = used ;
1106
+ frag -> binary_patch_method = patch_method ;
1107
+ return frag ;
1108
+
1059
1109
corrupt :
1060
- return error ("corrupt binary patch at line %d: %.*s" ,
1061
- linenr - 1 , llen - 1 , buffer );
1110
+ if (data )
1111
+ free (data );
1112
+ * status_p = -1 ;
1113
+ error ("corrupt binary patch at line %d: %.*s" ,
1114
+ linenr - 1 , llen - 1 , buffer );
1115
+ return NULL ;
1116
+ }
1117
+
1118
+ static int parse_binary (char * buffer , unsigned long size , struct patch * patch )
1119
+ {
1120
+ /* We have read "GIT binary patch\n"; what follows is a line
1121
+ * that says the patch method (currently, either "literal" or
1122
+ * "delta") and the length of data before deflating; a
1123
+ * sequence of 'length-byte' followed by base-85 encoded data
1124
+ * follows.
1125
+ *
1126
+ * When a binary patch is reversible, there is another binary
1127
+ * hunk in the same format, starting with patch method (either
1128
+ * "literal" or "delta") with the length of data, and a sequence
1129
+ * of length-byte + base-85 encoded data, terminated with another
1130
+ * empty line. This data, when applied to the postimage, produces
1131
+ * the preimage.
1132
+ */
1133
+ struct fragment * forward ;
1134
+ struct fragment * reverse ;
1135
+ int status ;
1136
+ int used , used_1 ;
1137
+
1138
+ forward = parse_binary_hunk (& buffer , & size , & status , & used );
1139
+ if (!forward && !status )
1140
+ /* there has to be one hunk (forward hunk) */
1141
+ return error ("unrecognized binary patch at line %d" , linenr - 1 );
1142
+ if (status )
1143
+ /* otherwise we already gave an error message */
1144
+ return status ;
1145
+
1146
+ reverse = parse_binary_hunk (& buffer , & size , & status , & used_1 );
1147
+ if (reverse )
1148
+ used += used_1 ;
1149
+ else if (status ) {
1150
+ /* not having reverse hunk is not an error, but having
1151
+ * a corrupt reverse hunk is.
1152
+ */
1153
+ free ((void * ) forward -> patch );
1154
+ free (forward );
1155
+ return status ;
1156
+ }
1157
+ forward -> next = reverse ;
1158
+ patch -> fragments = forward ;
1159
+ patch -> is_binary = 1 ;
1160
+ return used ;
1062
1161
}
1063
1162
1064
1163
static int parse_chunk (char * buffer , unsigned long size , struct patch * patch )
@@ -1505,59 +1604,36 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
1505
1604
return offset ;
1506
1605
}
1507
1606
1508
- static char * inflate_it (const void * data , unsigned long size ,
1509
- unsigned long inflated_size )
1510
- {
1511
- z_stream stream ;
1512
- void * out ;
1513
- int st ;
1514
-
1515
- memset (& stream , 0 , sizeof (stream ));
1516
-
1517
- stream .next_in = (unsigned char * )data ;
1518
- stream .avail_in = size ;
1519
- stream .next_out = out = xmalloc (inflated_size );
1520
- stream .avail_out = inflated_size ;
1521
- inflateInit (& stream );
1522
- st = inflate (& stream , Z_FINISH );
1523
- if ((st != Z_STREAM_END ) || stream .total_out != inflated_size ) {
1524
- free (out );
1525
- return NULL ;
1526
- }
1527
- return out ;
1528
- }
1529
-
1530
1607
static int apply_binary_fragment (struct buffer_desc * desc , struct patch * patch )
1531
1608
{
1532
1609
unsigned long dst_size ;
1533
1610
struct fragment * fragment = patch -> fragments ;
1534
1611
void * data ;
1535
1612
void * result ;
1536
1613
1537
- /* Binary patch is irreversible */
1538
- if (apply_in_reverse )
1539
- return error ( "cannot reverse-apply a binary patch to '%s'" ,
1540
- patch -> new_name
1541
- ? patch -> new_name : patch -> old_name );
1542
-
1543
- data = inflate_it ( fragment -> patch , fragment -> size ,
1544
- patch -> deflate_origlen ) ;
1545
- if (! data )
1546
- return error ( "corrupt patch data" ) ;
1547
- switch (patch -> is_binary ) {
1614
+ /* Binary patch is irreversible without the optional second hunk */
1615
+ if (apply_in_reverse ) {
1616
+ if (! fragment -> next )
1617
+ return error ( "cannot reverse-apply a binary patch "
1618
+ "without the reverse hunk to '%s'" ,
1619
+ patch -> new_name
1620
+ ? patch -> new_name : patch -> old_name );
1621
+ fragment = fragment ;
1622
+ }
1623
+ data = ( void * ) fragment -> patch ;
1624
+ switch (fragment -> binary_patch_method ) {
1548
1625
case BINARY_DELTA_DEFLATED :
1549
1626
result = patch_delta (desc -> buffer , desc -> size ,
1550
1627
data ,
1551
- patch -> deflate_origlen ,
1628
+ fragment -> size ,
1552
1629
& dst_size );
1553
1630
free (desc -> buffer );
1554
1631
desc -> buffer = result ;
1555
- free (data );
1556
1632
break ;
1557
1633
case BINARY_LITERAL_DEFLATED :
1558
1634
free (desc -> buffer );
1559
1635
desc -> buffer = data ;
1560
- dst_size = patch -> deflate_origlen ;
1636
+ dst_size = fragment -> size ;
1561
1637
break ;
1562
1638
}
1563
1639
if (!desc -> buffer )
0 commit comments