Skip to content

Commit

Permalink
Handle XML files format properly
Browse files Browse the repository at this point in the history
In A12 format of XML files changed to Android Binary XML
TWRP uses RapidXML to parse XMLs, but it don't support ABX format
So before parse check format of XML format and if it is in ABX, just ignore it for now

Change-Id: Ie40f5b3534db50143999984be22ade1d1af162e7
  • Loading branch information
epicX67 committed Nov 14, 2021
1 parent c45169e commit 0c8fc1a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 13 deletions.
70 changes: 57 additions & 13 deletions partitionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) + ")";
}
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -3569,3 +3586,30 @@ bool TWPartitionManager::Unmap_Super_Devices() {
}
return true;
}


bool TWPartitionManager::Check_Pending_Merges() {
auto sm = android::snapshot::SnapshotManager::NewForFirstStageMount();
if (!sm) {
LOGERR("Unable to call snapshot manager\n");
return false;
}

if (!Unmap_Super_Devices()) {
LOGERR("Unable to unmap dynamic partitions.\n");
return false;
}

auto callback = [&]() -> void {
double progress;
sm->GetUpdateState(&progress);
LOGINFO("waiting for merge to complete: %.2f\n", progress);
};

LOGINFO("checking for merges\n");
if (!sm->HandleImminentDataWipe(callback)) {
LOGERR("Unable to check merge status\n");
return false;
}
return true;
}
16 changes: 16 additions & 0 deletions twrp-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,4 +1512,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
1 change: 1 addition & 0 deletions twrp-functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class TWFunc
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);
Expand Down

0 comments on commit 0c8fc1a

Please sign in to comment.