Skip to content

Commit

Permalink
Merge pull request #70 from djpohly/brotli-bsdiff
Browse files Browse the repository at this point in the history
Implement `BROTLI_BSDIFF` chunk type
  • Loading branch information
vm03 authored Aug 6, 2024
2 parents 65248f4 + 8ebf841 commit 006ebdc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 662 deletions.
49 changes: 46 additions & 3 deletions payload_dumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
import bsdiff4
import io
import os
import brotli
try:
import lzma
except ImportError:
from backports import lzma

import update_metadata_pb2 as um

BSDF2_MAGIC = b'BSDF2'

flatten = lambda l: [item for sublist in l for item in sublist]

def u32(x):
Expand All @@ -22,6 +25,46 @@ def u32(x):
def u64(x):
return struct.unpack('>Q', x)[0]

def bsdf2_decompress(alg, data):
if alg == 0:
return data
elif alg == 1:
return bz2.decompress(data)
elif alg == 2:
return brotli.decompress(data)

# Adapted from bsdiff4.read_patch
def bsdf2_read_patch(fi):
"""read a bsdiff/BSDF2-format patch from stream 'fi'
"""
magic = fi.read(8)
if magic == bsdiff4.format.MAGIC:
# bsdiff4 uses bzip2 (algorithm 1)
alg_control = alg_diff = alg_extra = 1
elif magic[:5] == BSDF2_MAGIC:
alg_control = magic[5]
alg_diff = magic[6]
alg_extra = magic[7]
else:
raise ValueError("incorrect magic bsdiff/BSDF2 header")

# length headers
len_control = bsdiff4.core.decode_int64(fi.read(8))
len_diff = bsdiff4.core.decode_int64(fi.read(8))
len_dst = bsdiff4.core.decode_int64(fi.read(8))

# read the control header
bcontrol = bsdf2_decompress(alg_control, fi.read(len_control))
tcontrol = [(bsdiff4.core.decode_int64(bcontrol[i:i + 8]),
bsdiff4.core.decode_int64(bcontrol[i + 8:i + 16]),
bsdiff4.core.decode_int64(bcontrol[i + 16:i + 24]))
for i in range(0, len(bcontrol), 24)]

# read the diff and extra blocks
bdiff = bsdf2_decompress(alg_diff, fi.read(len_diff))
bextra = bsdf2_decompress(alg_extra, fi.read())
return len_dst, tcontrol, bdiff, bextra

def verify_contiguous(exts):
blocks = 0

Expand Down Expand Up @@ -61,9 +104,9 @@ def data_for_op(op,out_file,old_file):
old_file.seek(ext.start_block*block_size)
data = old_file.read(ext.num_blocks*block_size)
out_file.write(data)
elif op.type == op.SOURCE_BSDIFF:
elif op.type in (op.SOURCE_BSDIFF, op.BROTLI_BSDIFF):
if not args.diff:
print ("SOURCE_BSDIFF supported only for differential OTA")
print ("BSDIFF supported only for differential OTA")
sys.exit(-3)
out_file.seek(op.dst_extents[0].start_block*block_size)
tmp_buff = io.BytesIO()
Expand All @@ -74,7 +117,7 @@ def data_for_op(op,out_file,old_file):
tmp_buff.seek(0)
old_data = tmp_buff.read()
tmp_buff.seek(0)
tmp_buff.write(bsdiff4.patch(old_data, data))
tmp_buff.write(bsdiff4.core.patch(old_data, *bsdf2_read_patch(io.BytesIO(data))))
n = 0;
tmp_buff.seek(0)
for ext in op.dst_extents:
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
protobuf>=3.19.3, <=3.20.1
protobuf>=5.27.3
six>=1.16.0
bsdiff4>=1.1.5
brotli>=1.1.0
Loading

0 comments on commit 006ebdc

Please sign in to comment.