diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 9e37463b..b1ddb998 100755 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -1837,23 +1837,30 @@ void TWPartitionManager::Parse_Users() { user.userId = to_string(userId); // Attempt to get name of user. Fallback to user ID if this fails. - char* userFile = PageManager::LoadFileToBuffer("/data/system/users/" + to_string(userId) + ".xml", NULL); - if (userFile == NULL) { - user.userName = to_string(userId); + std::string path = "/data/system/users/" + to_string(userId) + ".xml"; + if ((atoi(TWFunc::System_Property_Get("ro.build.version.sdk").c_str()) > 30) && TWFunc::Path_Exists(path)) { + if(!TWFunc::Check_Xml_Format(path)) + user.userName = to_string(userId); } else { - xml_document<> *userXml = new xml_document<>(); - userXml->parse<0>(userFile); - xml_node<>* userNode = userXml->first_node("user"); - if (userNode == nullptr) { + char* userFile = PageManager::LoadFileToBuffer(path, NULL); + if (userFile == NULL) { user.userName = to_string(userId); - } else { - xml_node<>* nameNode = userNode->first_node("name"); - if (nameNode == nullptr) + } + else { + xml_document<> *userXml = new xml_document<>(); + userXml->parse<0>(userFile); + xml_node<>* userNode = userXml->first_node("user"); + if (userNode == nullptr) { user.userName = to_string(userId); - else { - string userName = nameNode->value(); - user.userName = userName + " (" + to_string(userId) + ")"; + } else { + xml_node<>* nameNode = userNode->first_node("name"); + if (nameNode == nullptr) + user.userName = to_string(userId); + else { + string userName = nameNode->value(); + user.userName = userName + " (" + to_string(userId) + ")"; + } } } } @@ -2985,6 +2992,16 @@ bool TWPartitionManager::Decrypt_Adopted() { LOGERR("Cannot decrypt adopted storage because /data will not mount\n"); return false; } + + // In Android 12 xml format changed. Previously it was human-readable format with xml tags + // now it's ABX (Android Binary Xml). Sadly, rapidxml can't parse it, so check xml format firstly + std::string path = "/data/system/storage.xml"; + if ((atoi(TWFunc::System_Property_Get("ro.build.version.sdk").c_str()) > 30) && TWFunc::Path_Exists(path)) + if(!TWFunc::Check_Xml_Format(path)) { + LOGINFO("Android 12+: storage.xml is in ABX format. Skipping adopted storage decryption\n"); + return false; + } + LOGINFO("Decrypt adopted storage starting\n"); char* xmlFile = PageManager::LoadFileToBuffer("/data/system/storage.xml", NULL); xml_document<> *doc = NULL; @@ -3595,4 +3612,4 @@ bool TWPartitionManager::Check_Pending_Merges() { return false; } return true; -} \ No newline at end of file +} diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 782afe1c..b1e9b26b 100755 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -1495,4 +1495,20 @@ string TWFunc::Check_For_TwrpFolder() { exit: return TW_DEFAULT_RECOVERY_FOLDER; } + +bool TWFunc::Check_Xml_Format(const std::string filename) { + std::string buffer(' ', 4); + std::string abx_hdr("ABX\x00", 4); + std::ifstream File; + File.open(filename); + if (File.is_open()) { + File.get(&buffer[0], buffer.size()); + File.close(); + // Android Binary Xml start from these bytes + if(!buffer.compare(0, abx_hdr.size(), abx_hdr)) + return false; // bad format, not possible to parse + } + return true; // good format, possible to parse +} + #endif // ndef BUILD_TWRPTAR_MAIN diff --git a/twrp-functions.hpp b/twrp-functions.hpp index 77ca1a23..89311a2b 100755 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -129,6 +129,7 @@ public: static void List_Mounts(); // List current mounts by the kernel static void Clear_Bootloader_Message(); // Removes the bootloader message from misc for next boot static string Check_For_TwrpFolder(); // Gets user defined path on storage where backups should be stored + static bool Check_Xml_Format(const std::string filename); // Return whether a xml is in plain xml or ABX format private: static void Copy_Log(string Source, string Destination);