system/corennnnn
修訂 | 8bc8da9139a297a50d557c12d74a47264817013e (tree) |
---|---|
時間 | 2016-07-20 18:01:29 |
作者 | taozha2x <taox.z.zhang@inte...> |
Commiter | Chih-Wei Huang |
Package Manager : optimization for ZipFileRO->NextEntry
In functions like findSurpportedAbi and CopyNativeLibraries, it using
ZipFileRO->NextEntry to get FileName of each file in package, and then find a
best ABI or do CRC checking for native libraries.
But in current implementation, NextEntry will read info from both CentralDirectoryRecord
and LocalFileHeader, to compare the filename, signature and so on to check the integrity.
But on platform that has bad "read" performance like Sofia 3GR, it cost too much
time reading infor from LocalFileHeader in each NextEntry, lead to so much time
scanning one package that contains dozens of binaries.
So add the NextEntryNoIntegrity API for such processing that just need a filename, like
use case mentioned above. But it might not trustable if package damaged or changed
unpredictable.
Together with patch in frameworks/base/
Change-Id: I915b60c4b3cfa9c17929b207149a03b73a197147
Tracked-On: https://jira01.devtools.intel.com/browse/OAM-5845
Signed-off-by: Shuo Gao <shuo.gao@intel.com>
Signed-off-by: Johnson Z Wu <johnson.z.wu@intel.com>
Signed-off-by: taozha2x <taox.z.zhang@intel.com>
Reviewed-on: https://android.intel.com:443/427235
@@ -165,6 +165,10 @@ int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, | ||
165 | 165 | */ |
166 | 166 | int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name); |
167 | 167 | |
168 | +#ifdef ZIP_NO_INTEGRITY | |
169 | +int32_t NextNoIntegrity(void* cookie, ZipEntry* data, ZipEntryName *name); | |
170 | +#endif | |
171 | + | |
168 | 172 | /* |
169 | 173 | * End iteration over all entries of a zip file and frees the memory allocated |
170 | 174 | * in StartIteration. |
@@ -24,6 +24,9 @@ LOCAL_STATIC_LIBRARIES := libz | ||
24 | 24 | LOCAL_SHARED_LIBRARIES := libutils libbase |
25 | 25 | LOCAL_MODULE:= libziparchive |
26 | 26 | LOCAL_CFLAGS := -Werror -Wall |
27 | +ifeq ($(ZIP_OPTIMIZATION_NO_INTEGRITY),true) | |
28 | + LOCAL_CFLAGS += -DZIP_NO_INTEGRITY | |
29 | +endif | |
27 | 30 | LOCAL_CPPFLAGS := -Wold-style-cast |
28 | 31 | include $(BUILD_STATIC_LIBRARY) |
29 | 32 |
@@ -34,7 +37,10 @@ LOCAL_STATIC_LIBRARIES := libz libutils libbase | ||
34 | 37 | LOCAL_MODULE:= libziparchive-host |
35 | 38 | LOCAL_CFLAGS := -Werror |
36 | 39 | ifneq ($(strip $(USE_MINGW)),) |
37 | - LOCAL_CFLAGS += -mno-ms-bitfields | |
40 | + LOCAL_CFLAGS += -mno-ms-bitfields | |
41 | +endif | |
42 | +ifeq ($(ZIP_OPTIMIZATION_NO_INTEGRITY),true) | |
43 | + LOCAL_CFLAGS += -DZIP_NO_INTEGRITY | |
38 | 44 | endif |
39 | 45 | LOCAL_MULTILIB := both |
40 | 46 | include $(BUILD_HOST_STATIC_LIBRARY) |
@@ -46,6 +52,9 @@ LOCAL_STATIC_LIBRARIES := libz libutils | ||
46 | 52 | LOCAL_SHARED_LIBRARIES := liblog libbase |
47 | 53 | LOCAL_MODULE:= libziparchive-host |
48 | 54 | LOCAL_CFLAGS := -Werror |
55 | +ifeq ($(ZIP_OPTIMIZATION_NO_INTEGRITY),true) | |
56 | + LOCAL_CFLAGS += -DZIP_NO_INTEGRITY | |
57 | +endif | |
49 | 58 | LOCAL_MULTILIB := both |
50 | 59 | include $(BUILD_HOST_SHARED_LIBRARY) |
51 | 60 |
@@ -54,6 +63,9 @@ include $(CLEAR_VARS) | ||
54 | 63 | LOCAL_MODULE := ziparchive-tests |
55 | 64 | LOCAL_CPP_EXTENSION := .cc |
56 | 65 | LOCAL_CFLAGS := -Werror |
66 | +ifeq ($(ZIP_OPTIMIZATION_NO_INTEGRITY),true) | |
67 | + LOCAL_CFLAGS += -DZIP_NO_INTEGRITY | |
68 | +endif | |
57 | 69 | LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc |
58 | 70 | LOCAL_SHARED_LIBRARIES := liblog libbase |
59 | 71 | LOCAL_STATIC_LIBRARIES := libziparchive libz libutils |
@@ -65,6 +77,9 @@ LOCAL_CPP_EXTENSION := .cc | ||
65 | 77 | LOCAL_CFLAGS += \ |
66 | 78 | -Werror \ |
67 | 79 | -Wno-unnamed-type-template-args |
80 | +ifeq ($(ZIP_OPTIMIZATION_NO_INTEGRITY),true) | |
81 | + LOCAL_CFLAGS += -DZIP_NO_INTEGRITY | |
82 | +endif | |
68 | 83 | LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc |
69 | 84 | LOCAL_SHARED_LIBRARIES := libziparchive-host liblog libbase |
70 | 85 | LOCAL_STATIC_LIBRARIES := \ |
@@ -712,6 +712,57 @@ static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, | ||
712 | 712 | #endif |
713 | 713 | } |
714 | 714 | |
715 | +#ifdef ZIP_NO_INTEGRITY | |
716 | +static int32_t FindEntryNoIntegrity(const ZipArchive* archive, const int ent, | |
717 | + ZipEntry* data) { | |
718 | + const uint16_t nameLen = archive->hash_table[ent].name_length; | |
719 | + | |
720 | + // Recover the start of the central directory entry from the filename | |
721 | + // pointer. The filename is the first entry past the fixed-size data, | |
722 | + // so we can just subtract back from that. | |
723 | + const uint8_t* ptr = archive->hash_table[ent].name; | |
724 | + ptr -= sizeof(CentralDirectoryRecord); | |
725 | + | |
726 | + // This is the base of our mmapped region, we have to sanity check that | |
727 | + // the name that's in the hash table is a pointer to a location within | |
728 | + // this mapped region. | |
729 | + const uint8_t* base_ptr = reinterpret_cast<const uint8_t*>( | |
730 | + archive->directory_map.getDataPtr()); | |
731 | + if (ptr < base_ptr || ptr > base_ptr + archive->directory_map.getDataLength()) { | |
732 | + ALOGW("Zip: Invalid entry pointer"); | |
733 | + return kInvalidOffset; | |
734 | + } | |
735 | + | |
736 | + const CentralDirectoryRecord *cdr = | |
737 | + reinterpret_cast<const CentralDirectoryRecord*>(ptr); | |
738 | + | |
739 | + // The offset of the start of the central directory in the zipfile. | |
740 | + // We keep this lying around so that we can sanity check all our lengths | |
741 | + // and our per-file structures. | |
742 | + const off64_t cd_offset = archive->directory_offset; | |
743 | + | |
744 | + // Fill out the compression method, modification time, crc32 | |
745 | + // and other interesting attributes from the central directory. These | |
746 | + // will later be compared against values from the local file header. | |
747 | + data->method = cdr->compression_method; | |
748 | + data->mod_time = cdr->last_mod_time; | |
749 | + data->crc32 = cdr->crc32; | |
750 | + data->compressed_length = cdr->compressed_size; | |
751 | + data->uncompressed_length = cdr->uncompressed_size; | |
752 | + | |
753 | + // Figure out the local header offset from the central directory. The | |
754 | + // actual file data will begin after the local header and the name / | |
755 | + // extra comments. | |
756 | + const off64_t local_header_offset = cdr->local_file_header_offset; | |
757 | + if (local_header_offset + static_cast<off64_t>(sizeof(LocalFileHeader)) >= cd_offset) { | |
758 | + ALOGW("Zip: bad local hdr offset in zip"); | |
759 | + return kInvalidOffset; | |
760 | + } | |
761 | + | |
762 | + return 0; | |
763 | +} | |
764 | +#endif | |
765 | + | |
715 | 766 | static int32_t FindEntry(const ZipArchive* archive, const int ent, |
716 | 767 | ZipEntry* data) { |
717 | 768 | const uint16_t nameLen = archive->hash_table[ent].name_length; |
@@ -881,6 +932,49 @@ struct IterationHandle { | ||
881 | 932 | } |
882 | 933 | }; |
883 | 934 | |
935 | +#ifdef ZIP_NO_INTEGRITY | |
936 | +int32_t NextNoIntegrity(void* cookie, ZipEntry* data, ZipEntryName* name) { | |
937 | + IterationHandle* handle = reinterpret_cast<IterationHandle*>(cookie); | |
938 | + if (handle == NULL) { | |
939 | + return kInvalidHandle; | |
940 | + } | |
941 | + | |
942 | + ZipArchive* archive = handle->archive; | |
943 | + if (archive == NULL || archive->hash_table == NULL) { | |
944 | + ALOGW("Zip: Invalid ZipArchiveHandle"); | |
945 | + return kInvalidHandle; | |
946 | + } | |
947 | + | |
948 | + const uint32_t currentOffset = handle->position; | |
949 | + const uint32_t hash_table_length = archive->hash_table_size; | |
950 | + const ZipEntryName *hash_table = archive->hash_table; | |
951 | + | |
952 | + for (uint32_t i = currentOffset; i < hash_table_length; ++i) { | |
953 | + if (hash_table[i].name != NULL && | |
954 | + (handle->prefix_len == 0 || | |
955 | + (hash_table[i].name_length >= handle->prefix_len && | |
956 | + memcmp(handle->prefix, hash_table[i].name, handle->prefix_len) == 0)) && | |
957 | + (handle->suffix_len == 0 || | |
958 | + (hash_table[i].name_length >= handle->suffix_len && | |
959 | + memcmp(handle->suffix, | |
960 | + hash_table[i].name + hash_table[i].name_length - handle->suffix_len, | |
961 | + handle->suffix_len) == 0))) { | |
962 | + handle->position = (i + 1); | |
963 | + const int error = FindEntryNoIntegrity(archive, i, data); | |
964 | + if (!error) { | |
965 | + name->name = hash_table[i].name; | |
966 | + name->name_length = hash_table[i].name_length; | |
967 | + } | |
968 | + | |
969 | + return error; | |
970 | + } | |
971 | + } | |
972 | + | |
973 | + handle->position = 0; | |
974 | + return kIterationEnd; | |
975 | +} | |
976 | +#endif | |
977 | + | |
884 | 978 | int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, |
885 | 979 | const ZipEntryName* optional_prefix, |
886 | 980 | const ZipEntryName* optional_suffix) { |