summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Compostella2015-04-03 07:31:19 -0500
committerJeremy Compostella2015-04-08 03:10:17 -0500
commitcfd3a03d3d147fca7a33d6f583b7047c5351fc32 (patch)
treeab6ba56dac1b2de967a248cfb90324d5d2e3ca8a /libsparse
parent27cda9a535c80470e913156e412cbf7e60c3217c (diff)
downloadplatform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.tar.gz
platform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.tar.xz
platform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.zip
libsparse: move_chunks_up_to_len() does not account skip chunks
I caught the fastboot host command sending more data than the fastboot device can accept. Fastboot host command was sending 36 surplus bytes because of 3 skip chunks that were not taken into account in move_chunks_up_to_len() algorithm. Change-Id: I39a4a033c9b15893bd70e553f17116735ee4a48e
Diffstat (limited to 'libsparse')
-rw-r--r--libsparse/sparse.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 65c09e0d4..311678a34 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -238,14 +238,15 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
238 struct backed_block *last_bb = NULL; 238 struct backed_block *last_bb = NULL;
239 struct backed_block *bb; 239 struct backed_block *bb;
240 struct backed_block *start; 240 struct backed_block *start;
241 unsigned int last_block = 0;
241 int64_t file_len = 0; 242 int64_t file_len = 0;
242 int ret; 243 int ret;
243 244
244 /* 245 /*
245 * overhead is sparse file header, initial skip chunk, split chunk, end 246 * overhead is sparse file header, the potential end skip
246 * skip chunk, and crc chunk. 247 * chunk and crc chunk.
247 */ 248 */
248 int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) + 249 int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) +
249 sizeof(uint32_t); 250 sizeof(uint32_t);
250 len -= overhead; 251 len -= overhead;
251 252
@@ -258,6 +259,11 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
258 259
259 for (bb = start; bb; bb = backed_block_iter_next(bb)) { 260 for (bb = start; bb; bb = backed_block_iter_next(bb)) {
260 count = 0; 261 count = 0;
262 if (backed_block_block(bb) > last_block)
263 count += sizeof(chunk_header_t);
264 last_block = backed_block_block(bb) +
265 DIV_ROUND_UP(backed_block_len(bb), to->block_size);
266
261 /* will call out_counter_write to update count */ 267 /* will call out_counter_write to update count */
262 ret = sparse_file_write_block(out_counter, bb); 268 ret = sparse_file_write_block(out_counter, bb);
263 if (ret) { 269 if (ret) {
@@ -270,6 +276,7 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
270 * requested size, split the chunk. Results in sparse files that 276 * requested size, split the chunk. Results in sparse files that
271 * are at least 7/8ths of the requested size 277 * are at least 7/8ths of the requested size
272 */ 278 */
279 file_len += sizeof(chunk_header_t);
273 if (!last_bb || (len - file_len > (len / 8))) { 280 if (!last_bb || (len - file_len > (len / 8))) {
274 backed_block_split(from->backed_block_list, bb, len - file_len); 281 backed_block_split(from->backed_block_list, bb, len - file_len);
275 last_bb = bb; 282 last_bb = bb;