Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix running some file formats from the Downloads folder #17466

Merged
merged 2 commits into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions Common/File/AndroidContentURI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ AndroidContentURI AndroidContentURI::WithRootFilePath(const std::string &filePat

AndroidContentURI AndroidContentURI::WithComponent(const std::string &filePath) {
AndroidContentURI uri = *this;
uri.file = uri.file + "/" + filePath;
if (uri.file.empty()) {
// Not sure what to do.
return uri;
}
if (uri.file.back() == ':') {
// Special case handling for Document URIs: Treat the ':' as a directory separator too (but preserved in the filename).
uri.file = uri.file + filePath;
} else {
uri.file = uri.file + "/" + filePath;
}
return uri;
}

Expand Down Expand Up @@ -94,10 +103,11 @@ AndroidContentURI AndroidContentURI::WithReplacedExtension(const std::string &ne
}

bool AndroidContentURI::CanNavigateUp() const {
if (root.empty()) {
return false;
if (IsTreeURI()) {
return file.size() > root.size();
} else {
return file.find(':') != std::string::npos && file.back() != ':';
}
return file.size() > root.size();
}

// Only goes downwards in hierarchies. No ".." will ever be generated.
Expand Down Expand Up @@ -141,12 +151,20 @@ std::string AndroidContentURI::GetLastPart() const {
if (colon == std::string::npos) {
return std::string();
}
if (file.back() == ':') {
return file;
}
return file.substr(colon + 1);
}

size_t slash = file.rfind('/');
if (slash == std::string::npos) {
return std::string();
// ok, look for the final colon. If it's the last char, we would have been caught above in !CanNavigateUp.
size_t colon = file.rfind(':');
if (colon == std::string::npos) {
return std::string();
}
return file.substr(colon + 1);
}

std::string part = file.substr(slash + 1);
Expand All @@ -160,7 +178,13 @@ bool AndroidContentURI::NavigateUp() {

size_t slash = file.rfind('/');
if (slash == std::string::npos) {
return false;
// ok, look for the final colon.
size_t colon = file.rfind(':');
if (colon == std::string::npos) {
return false;
}
file = file.substr(0, colon + 1); // Note: we include the colon in these paths.
return true;
}

file = file.substr(0, slash);
Expand Down
4 changes: 4 additions & 0 deletions Common/File/AndroidContentURI.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ class AndroidContentURI {
const std::string &RootPath() const {
return root.empty() ? file : root;
}

bool IsTreeURI() const {
return !root.empty();
}
};
14 changes: 10 additions & 4 deletions unittest/UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,14 +722,20 @@ static bool TestAndroidContentURI() {
EXPECT_EQ_STR(diff, std::string("Tekken 6.iso"));

EXPECT_EQ_STR(fileURI.GetFileExtension(), std::string(".prx"));
EXPECT_FALSE(fileURI.CanNavigateUp());
EXPECT_TRUE(fileURI.CanNavigateUp()); // Can now virtually navigate up one step from these.

// These are annoying because they hide the actual filename, and we can't get at a parent folder,
// which confuses our elf loading.
// These are annoying because they hide the actual filename, and we can't get at a parent folder.
// Decided to handle the ':' as a directory separator for navigation purposes, which fixes the problem (though not the extension thing).
AndroidContentURI downloadURI;
EXPECT_TRUE(downloadURI.Parse(std::string(downloadURIString)));
EXPECT_EQ_STR(downloadURI.GetLastPart(), std::string("10000000006"));
EXPECT_FALSE(downloadURI.CanNavigateUp());
EXPECT_TRUE(downloadURI.CanNavigateUp());
EXPECT_TRUE(downloadURI.NavigateUp());
// While this is not an openable valid content URI, we can still get something that we can concatenate a filename on top of.
EXPECT_EQ_STR(downloadURI.ToString(), std::string("content://com.android.providers.downloads.documents/document/msf%3A"));
EXPECT_EQ_STR(downloadURI.GetLastPart(), std::string("msf:"));
downloadURI = downloadURI.WithComponent("myfile");
EXPECT_EQ_STR(downloadURI.ToString(), std::string("content://com.android.providers.downloads.documents/document/msf%3Amyfile"));
return true;
}

Expand Down