28
28
#include <limits.h>
29
29
#include "bspatch.h"
30
30
31
- static int64_t offtin (uint8_t * buf )
31
+ // Converts signed magnitude to two's complement.
32
+ static inline void offtin (int64_t * x )
32
33
{
33
- int64_t y ;
34
-
35
- y = buf [7 ]& 0x7F ;
36
- y = y * 256 ;y += buf [6 ];
37
- y = y * 256 ;y += buf [5 ];
38
- y = y * 256 ;y += buf [4 ];
39
- y = y * 256 ;y += buf [3 ];
40
- y = y * 256 ;y += buf [2 ];
41
- y = y * 256 ;y += buf [1 ];
42
- y = y * 256 ;y += buf [0 ];
43
-
44
- if (buf [7 ]& 0x80 ) y = - y ;
45
-
46
- return y ;
34
+ if (* x < 0 )
35
+ * x = (~* x + 1 ) | INT64_MIN ;
47
36
}
48
37
49
- int bspatch (const uint8_t * source , int64_t sourcesize , uint8_t * target , int64_t targetsize , struct bspatch_stream * stream )
38
+ int bspatch (const uint8_t * source , const int64_t sourcesize , uint8_t * target ,
39
+ const int64_t targetsize , struct bspatch_stream * stream )
50
40
{
51
- uint8_t buf [8 ];
52
- int64_t oldpos ,newpos ;
41
+ int64_t oldpos = 0 , newpos = 0 ;
53
42
int64_t ctrl [3 ];
54
- int64_t i ;
55
-
56
- oldpos = 0 ;newpos = 0 ;
57
- while (newpos < targetsize ) {
58
- /* Read control data */
59
- for (i = 0 ;i <=2 ;i ++ ) {
60
- if (stream -> read (stream , buf , 8 , BSDIFF_READCONTROL ))
61
- return -1 ;
62
- ctrl [i ]= offtin (buf );
63
- };
64
-
65
- /* Sanity-check */
66
- if (ctrl [0 ]< 0 || ctrl [0 ]> INT_MAX ||
67
- ctrl [1 ]< 0 || ctrl [1 ]> INT_MAX ||
68
- newpos + ctrl [0 ]> targetsize )
43
+
44
+ while (newpos < targetsize )
45
+ {
46
+ // Reads control data block.
47
+ if (stream -> read (stream , ctrl , sizeof (ctrl ), BSDIFF_READCONTROL ))
69
48
return -1 ;
49
+ for (int i = 0 ; i <= 2 ; ++ i )
50
+ offtin (ctrl + i );
70
51
71
- /* Read diff string */
72
- if (stream -> read ( stream , target + newpos , ( int ) ctrl [0 ], BSDIFF_READDIFF ) )
52
+ // Checks sanity of diff control data.
53
+ if (ctrl [ 0 ] < 0 || ctrl [0 ] > targetsize - newpos )
73
54
return -1 ;
74
55
75
- /* Add old data to diff string */
76
- for (i = 0 ;i < ctrl [0 ];i ++ )
77
- if ((oldpos + i >=0 ) && (oldpos + i < sourcesize ))
78
- target [newpos + i ]+= source [oldpos + i ];
56
+ // Reads diff data block.
57
+ if (stream -> read (stream , target + newpos , ctrl [0 ], BSDIFF_READDIFF ))
58
+ return -1 ;
79
59
80
- /* Adjust pointers */
81
- newpos += ctrl [0 ];
82
- oldpos += ctrl [0 ];
60
+ // Adds old data to the diff data.
61
+ if (oldpos < 0 || oldpos + ctrl [0 ] < 0 || oldpos + ctrl [0 ] > sourcesize )
62
+ return -1 ;
63
+ for (int64_t i = 0 ; i < ctrl [0 ]; ++ i )
64
+ target [newpos + i ] += source [oldpos + i ];
83
65
84
- /* Sanity-check */
85
- if (newpos + ctrl [1 ]> targetsize )
66
+ // Adjusts position pointers.
67
+ newpos += ctrl [0 ];
68
+ oldpos += ctrl [0 ];
69
+
70
+ // Checks sanity of extra control data.
71
+ if (ctrl [1 ] < 0 || ctrl [1 ] > targetsize - newpos )
86
72
return -1 ;
87
73
88
- /* Read extra string */
89
- if (stream -> read (stream , target + newpos , ( int ) ctrl [1 ], BSDIFF_READEXTRA ))
74
+ // Reads extra data block.
75
+ if (stream -> read (stream , target + newpos , ctrl [1 ], BSDIFF_READEXTRA ))
90
76
return -1 ;
91
77
92
- /* Adjust pointers */
78
+ // Adjust position pointers.
93
79
newpos += ctrl [1 ];
94
80
oldpos += ctrl [2 ];
95
81
};
@@ -103,16 +89,18 @@ int bspatch(const uint8_t* source, int64_t sourcesize, uint8_t* target, int64_t
103
89
#include <string.h>
104
90
#include "common.h"
105
91
106
- static int bz2_read (const struct bspatch_stream * stream , void * buffer , int length , ATTR_UNUSED int type )
92
+ static int bz2_read (const struct bspatch_stream * stream , void * buffer ,
93
+ size_t length , ATTR_UNUSED enum bspatch_stream_type type )
107
94
{
108
- int n ;
109
- int bz2err ;
110
- BZFILE * bz2 ;
111
-
112
- bz2 = (BZFILE * )stream -> opaque ;
113
- n = BZ2_bzRead (& bz2err , bz2 , buffer , length );
114
- if (n != length )
115
- return -1 ;
95
+ size_t bytes_read = 0 ;
96
+ int to_read ;
97
+ while ((to_read = (int )min (length - bytes_read , 1048576 )) != 0 )
98
+ {
99
+ int bz2err ;
100
+ if (BZ2_bzRead (& bz2err , (BZFILE * )stream -> opaque , (uint8_t * )buffer + bytes_read , to_read ) != to_read )
101
+ return -1 ;
102
+ bytes_read += to_read ;
103
+ }
116
104
117
105
return 0 ;
118
106
}
@@ -148,7 +136,7 @@ int main(int argc, char * argv[])
148
136
errx (1 , "Corrupt patch header (magic)\n" );
149
137
150
138
// Reads target size from header
151
- targetsize = offtin (header + 16 );
139
+ targetsize = * ( int64_t * ) (header + 16 );
152
140
if (targetsize < 0 )
153
141
errx (1 , "Corrupt patch header (target size)\n" );
154
142
0 commit comments