From b85d9b2a32949d0cfd6a78701da6597a7aec39d0 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Mon, 19 Nov 2018 12:11:38 -0800 Subject: [PATCH] Fix copying null reference across themes When themes have two different AssetManagers, we only copy attributes that exist in both the themes. If the value of the attribute or reference is equal to 0 (a null reference but not using the TYPE_NULL type), do not attempt to fix the package id of that null reference. Bug: 119522708 Test: manual test of broken app Change-Id: Id615d5a47b7f121b08bbba885d106b9cd3f54afc --- libs/androidfw/AssetManager2.cpp | 51 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 9e6948878b1de..37717a83ccc7c 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -1183,8 +1183,32 @@ void Theme::SetTo(const Theme& o) { continue; } - // The package id of the attribute needs to be rewritten to the package id of the value in - // the destination + // If the attribute value represents an attribute or reference, the package id of the + // value needs to be rewritten to the package id of the value in the destination + uint32_t attribue_data = entry.value.data; + if ((entry.value.dataType == Res_value::TYPE_ATTRIBUTE + || entry.value.dataType == Res_value::TYPE_REFERENCE + || entry.value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE + || entry.value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE) + && attribue_data != 0x0) { + + // Determine the package id of the reference in the destination AssetManager + auto value_package_map = src_asset_cookie_id_map.find(entry.cookie); + if (value_package_map == src_asset_cookie_id_map.end()) { + continue; + } + + auto value_dest_package = value_package_map->second.find( + get_package_id(entry.value.data)); + if (value_dest_package == value_package_map->second.end()) { + continue; + } + + attribue_data = fix_package_id(entry.value.data, value_dest_package->second); + } + + // The package id of the attribute needs to be rewritten to the package id of the + // attribute in the destination int attribute_dest_package_id = p; if (attribute_dest_package_id != 0x01) { // Find the cookie of the attribute resource id @@ -1206,29 +1230,6 @@ void Theme::SetTo(const Theme& o) { attribute_dest_package_id = attribute_dest_package->second; } - // If the attribute value represents an attribute or reference, the package id of the - // value needs to be rewritten to the package id of the value in the destination - uint32_t attribue_data = entry.value.data; - if (entry.value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE - || entry.value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE - || entry.value.dataType == Res_value::TYPE_ATTRIBUTE - || entry.value.dataType == Res_value::TYPE_REFERENCE) { - - // Determine the package id of the reference in the destination AssetManager - auto value_package_map = src_asset_cookie_id_map.find(entry.cookie); - if (value_package_map == src_asset_cookie_id_map.end()) { - continue; - } - - auto value_dest_package = value_package_map->second.find( - get_package_id(entry.value.data)); - if (value_dest_package == value_package_map->second.end()) { - continue; - } - - attribue_data = fix_package_id(entry.value.data, value_dest_package->second); - } - // Lazily instantiate the destination package std::unique_ptr& dest_package = packages_[attribute_dest_package_id]; if (dest_package == nullptr) {