Kelvin Zhang | 25ab998 | 2021-06-22 09:51:34 -0400 | [diff] [blame] | 1 | # Copyright (C) 2021 The Android Open Source Project |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | |
| 15 | |
| 16 | import unittest |
| 17 | import io |
| 18 | import ota_utils |
| 19 | import zipfile |
| 20 | |
| 21 | |
| 22 | class TestZipEntryOffset(unittest.TestCase): |
| 23 | def test_extra_length_differ(self): |
| 24 | # This is a magic zip file such that: |
| 25 | # 1. It has 1 entry, `file.txt'` |
| 26 | # 2. The central directory entry for the entry contains an extra field of# |
| 27 | # length 24, while the local file header for the entry contains an extra# |
| 28 | # field of length 28. |
| 29 | # It is key that the entry contains extra field of different length. |
| 30 | # The sole purpose of this test case is make sure our offset computing |
| 31 | # logic works in this scenario. |
| 32 | |
| 33 | # This is created by: |
| 34 | # touch file.txt |
| 35 | # zip -0 test.zip file.txt |
| 36 | # Above command may or may not work on all platforms. |
| 37 | # Some zip implementation will keep the extra field size consistent. |
| 38 | # Some don't |
| 39 | magic_zip = b'PK\x03\x04\n\x00\x00\x00\x00\x00nY\xfcR\x00\x00\x00\x00\x00\x00\x00' +\ |
| 40 | b'\x00\x00\x00\x00\x00\x08\x00\x1c\x00file.txtUT\t\x00\x03' +\ |
| 41 | b'\xa0s\x01a\xa0s\x01aux\x0b\x00\x01\x04\x88\xc4\t\x00\x04S_\x01\x00' +\ |
| 42 | b'PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00nY\xfcR\x00\x00\x00\x00' +\ |
| 43 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x18\x00\x00\x00\x00\x00' +\ |
| 44 | b'\x00\x00\x00\x00\x80\x81\x00\x00\x00\x00file.txt' +\ |
| 45 | b'UT\x05\x00\x03\xa0s\x01aux\x0b\x00\x01\x04\x88\xc4\t\x00\x04' +\ |
| 46 | b'S_\x01\x00PK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00N\x00\x00' +\ |
| 47 | b'\x00B\x00\x00\x00\x00\x00' |
| 48 | # Just making sure we concatenated the bytes correctly |
| 49 | self.assertEqual(len(magic_zip), 166) |
| 50 | fp = io.BytesIO(magic_zip) |
| 51 | with zipfile.ZipFile(fp, 'r') as zfp: |
| 52 | self.assertGreater(len(zfp.infolist()), 0) |
| 53 | zinfo = zfp.getinfo("file.txt") |
| 54 | (offset, size) = ota_utils.GetZipEntryOffset(zfp, zinfo) |
| 55 | self.assertEqual(size, zinfo.file_size) |
| 56 | self.assertEqual(offset, zipfile.sizeFileHeader+len(zinfo.filename) + 28) |