diff options
author | Tao Bao <tbao@google.com> | 2015-09-05 20:35:32 -0700 |
---|---|---|
committer | Tao Bao <tbao@google.com> | 2015-09-08 10:55:32 -0700 |
commit | 28f6f9c3deb4d23fd627d15631d682a5cfa989fc (patch) | |
tree | a3b969ed8f925a4d836c39faca7cf74733ffc957 /tools/releasetools | |
parent | a6e6afbce69da968299898944bb2165f5e799886 (diff) | |
download | build-28f6f9c3deb4d23fd627d15631d682a5cfa989fc.zip build-28f6f9c3deb4d23fd627d15631d682a5cfa989fc.tar.gz build-28f6f9c3deb4d23fd627d15631d682a5cfa989fc.tar.bz2 |
releasetools: Always write the last block if it's padded.
In BBOTAs if the last block of a DataImage is padded, we should always
write the whole block even for incremental OTAs. Because otherwise the
last block may be skipped if unchanged, but would fail the post-install
verification if it has non-zero contents in the padding bytes.
Bug: 23828506
Change-Id: I6f6789eec568ed0b808b9e425f5ecdbea1bdf446
(cherry picked from commit 7589e961a7b8b7d964704db87f83ed8811e97ac6)
Diffstat (limited to 'tools/releasetools')
-rw-r--r-- | tools/releasetools/blockimgdiff.py | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py index a1b3eda..cb6fc85 100644 --- a/tools/releasetools/blockimgdiff.py +++ b/tools/releasetools/blockimgdiff.py @@ -106,11 +106,13 @@ class DataImage(Image): assert not (trim and pad) partial = len(self.data) % self.blocksize + padded = False if partial > 0: if trim: self.data = self.data[:-partial] elif pad: self.data += '\0' * (self.blocksize - partial) + padded = True else: raise ValueError(("data for DataImage must be multiple of %d bytes " "unless trim or pad is specified") % @@ -120,14 +122,23 @@ class DataImage(Image): self.total_blocks = len(self.data) / self.blocksize self.care_map = RangeSet(data=(0, self.total_blocks)) - self.clobbered_blocks = RangeSet() + # When the last block is padded, we always write the whole block even for + # incremental OTAs. Because otherwise the last block may get skipped if + # unchanged for an incremental, but would fail the post-install + # verification if it has non-zero contents in the padding bytes. + # Bug: 23828506 + if padded: + self.clobbered_blocks = RangeSet( + data=(self.total_blocks-1, self.total_blocks)) + else: + self.clobbered_blocks = RangeSet() self.extended = RangeSet() zero_blocks = [] nonzero_blocks = [] reference = '\0' * self.blocksize - for i in range(self.total_blocks): + for i in range(self.total_blocks-1 if padded else self.total_blocks): d = self.data[i*self.blocksize : (i+1)*self.blocksize] if d == reference: zero_blocks.append(i) @@ -139,14 +150,18 @@ class DataImage(Image): self.file_map = {"__ZERO": RangeSet(zero_blocks), "__NONZERO": RangeSet(nonzero_blocks)} + if self.clobbered_blocks: + self.file_map["__COPY"] = self.clobbered_blocks + def ReadRangeSet(self, ranges): return [self.data[s*self.blocksize:e*self.blocksize] for (s, e) in ranges] def TotalSha1(self, include_clobbered_blocks=False): - # DataImage always carries empty clobbered_blocks, so - # include_clobbered_blocks can be ignored. - assert self.clobbered_blocks.size() == 0 - return sha1(self.data).hexdigest() + if not include_clobbered_blocks: + ranges = self.care_map.subtract(self.clobbered_blocks) + return sha1(self.ReadRangeSet(ranges)).hexdigest() + else: + return sha1(self.data).hexdigest() class Transfer(object): |