From 05f87d6ccaa2d4666dd97cb1d2eeb88bd4e5306f Mon Sep 17 00:00:00 2001 From: Vojtech Bocek Date: Tue, 11 Mar 2014 22:08:23 +0100 Subject: Fix skipping of relative paths and lost+found in twrpDU Change-Id: Ib79029fd6237502338b041a6bc2f9e539536d6ad Signed-off-by: Vojtech Bocek --- twrp-functions.cpp | 25 +++++++++++++++++++++++++ twrp-functions.hpp | 1 + twrpDU.cpp | 51 +++++++++++++++++++++++++++------------------------ twrpDU.hpp | 9 ++++++--- twrpTar.cpp | 15 +++------------ 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/twrp-functions.cpp b/twrp-functions.cpp index c50290df4..4551e84b4 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -274,6 +274,31 @@ unsigned long TWFunc::Get_File_Size(string Path) { return st.st_size; } +std::string TWFunc::Remove_Trailing_Slashes(const std::string& path, bool leaveLast) +{ + std::string res; + size_t last_idx = 0, idx = 0; + + while(last_idx != std::string::npos) + { + if(last_idx != 0) + res += '/'; + + idx = path.find_first_of('/', last_idx); + if(idx == std::string::npos) { + res += path.substr(last_idx, idx); + break; + } + + res += path.substr(last_idx, idx-last_idx); + last_idx = path.find_first_not_of('/', idx); + } + + if(leaveLast) + res += '/'; + return res; +} + #ifndef BUILD_TWRPTAR_MAIN // Returns "/path" from a full /path/to/file.name diff --git a/twrp-functions.hpp b/twrp-functions.hpp index 661ca02db..64a45f55b 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -49,6 +49,7 @@ public: static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format static unsigned long Get_File_Size(string Path); // Returns the size of a file + static std::string Remove_Trailing_Slashes(const std::string& path, bool leaveLast = false); // Normalizes the path, e.g /data//media/ -> /data/media #ifndef BUILD_TWRPTAR_MAIN static void install_htc_dumlock(void); // Installs HTC Dumlock diff --git a/twrpDU.cpp b/twrpDU.cpp index c4446d42a..d2345d768 100644 --- a/twrpDU.cpp +++ b/twrpDU.cpp @@ -27,19 +27,21 @@ extern "C" { #include #include #include +#include #include "twrpDU.hpp" +#include "twrp-functions.hpp" using namespace std; twrpDU::twrpDU() { add_relative_dir("."); add_relative_dir(".."); - add_relative_dir("lost_found"); + add_relative_dir("lost+found"); add_absolute_dir("/data/data/com.google.android.music/files"); parent = ""; } -void twrpDU::add_relative_dir(string dir) { +void twrpDU::add_relative_dir(const string& dir) { relativedir.push_back(dir); } @@ -53,8 +55,8 @@ void twrpDU::clear_relative_dir(string dir) { } } -void twrpDU::add_absolute_dir(string dir) { - absolutedir.push_back(dir); +void twrpDU::add_absolute_dir(const string& dir) { + absolutedir.push_back(TWFunc::Remove_Trailing_Slashes(dir)); } vector twrpDU::get_absolute_dirs(void) { @@ -79,12 +81,7 @@ uint64_t twrpDU::Get_Folder_Size(const string& Path) { while ((de = readdir(d)) != NULL) { - bool skip_dir = false; - if (de->d_type == DT_DIR) { - string dir = de->d_name; - skip_dir = check_skip_dirs(dir); - } - if (de->d_type == DT_DIR && !skip_dir) { + if (de->d_type == DT_DIR && !check_skip_dirs(Path, de->d_name)) { dutemp = Get_Folder_Size((Path + "/" + de->d_name)); dusize += dutemp; dutemp = 0; @@ -98,19 +95,25 @@ uint64_t twrpDU::Get_Folder_Size(const string& Path) { return dusize; } -bool twrpDU::check_skip_dirs(string& dir) { - bool result = false; - for (int i = 0; i < relativedir.size(); ++i) { - if (dir == relativedir.at(i)) { - result = true; - break; - } - } - for (int i = 0; i < absolutedir.size(); ++i) { - if (dir == absolutedir.at(i)) { - result = true; - break; - } +bool twrpDU::check_relative_skip_dirs(const string& dir) { + return std::find(relativedir.begin(), relativedir.end(), dir) != relativedir.end(); +} + +bool twrpDU::check_absolute_skip_dirs(const string& path) { + string normalized = TWFunc::Remove_Trailing_Slashes(path); + return std::find(absolutedir.begin(), absolutedir.end(), normalized) != absolutedir.end(); +} + +bool twrpDU::check_skip_dirs(const string& parent, const string& dir) { + return check_relative_skip_dirs(dir) || check_absolute_skip_dirs(parent + "/" + dir); +} + +bool twrpDU::check_skip_dirs(const string& path) { + string normalized = TWFunc::Remove_Trailing_Slashes(path); + size_t slashIdx = normalized.find_last_of('/'); + if(slashIdx != std::string::npos && slashIdx+1 < normalized.size()) { + if(check_relative_skip_dirs(normalized.substr(slashIdx+1))) + return true; } - return result; + return check_absolute_skip_dirs(normalized); } diff --git a/twrpDU.hpp b/twrpDU.hpp index dac15f126..91f5039a7 100644 --- a/twrpDU.hpp +++ b/twrpDU.hpp @@ -38,9 +38,12 @@ class twrpDU { public: twrpDU(); uint64_t Get_Folder_Size(const string& Path); // Gets the folder's size using stat - void add_absolute_dir(string Path); - void add_relative_dir(string Path); - bool check_skip_dirs(string& dir); + void add_absolute_dir(const string& Path); + void add_relative_dir(const string& Path); + bool check_relative_skip_dirs(const string& dir); + bool check_absolute_skip_dirs(const string& path); + bool check_skip_dirs(const string& parent, const string& dir); + bool check_skip_dirs(const string& path); vector get_absolute_dirs(void); void clear_relative_dir(string dir); private: diff --git a/twrpTar.cpp b/twrpTar.cpp index a31fe1221..c024821ab 100644 --- a/twrpTar.cpp +++ b/twrpTar.cpp @@ -124,10 +124,7 @@ int twrpTar::createTarFork() { continue; // Skip /data/media if (de->d_type == DT_BLK || de->d_type == DT_CHR) continue; - bool skip_dir = false; - string dir(de->d_name); - skip_dir = du.check_skip_dirs(dir); - if (de->d_type == DT_DIR && !skip_dir) { + if (de->d_type == DT_DIR && !du.check_skip_dirs(tardir, de->d_name)) { item_len = strlen(de->d_name); if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) { if (Generate_TarList(FileName, &RegularList, &target_size, ®ular_thread_id) < 0) { @@ -171,10 +168,7 @@ int twrpTar::createTarFork() { continue; // Skip /data/media if (de->d_type == DT_BLK || de->d_type == DT_CHR) continue; - bool skip_dir = false; - string dir(de->d_name); - skip_dir = du.check_skip_dirs(dir); - if (de->d_type == DT_DIR && !skip_dir) { + if (de->d_type == DT_DIR && !du.check_skip_dirs(tardir, de->d_name)) { item_len = strlen(de->d_name); if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) { // Do nothing, we added these to RegularList earlier @@ -485,10 +479,7 @@ int twrpTar::Generate_TarList(string Path, std::vector *TarList, continue; TarItem.fn = FileName; TarItem.thread_id = *thread_id; - bool skip_dir = false; - string dir(de->d_name); - skip_dir = du.check_skip_dirs(dir); - if (de->d_type == DT_DIR && !skip_dir) { + if (de->d_type == DT_DIR && !du.check_skip_dirs(Path, de->d_name)) { TarList->push_back(TarItem); if (Generate_TarList(FileName, TarList, Target_Size, thread_id) < 0) return -1; -- cgit v1.2.3