mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 12:27:21 +12:00
[FS] Add app data folder, add path safety checks
This commit is contained in:
parent
c16bf5c8aa
commit
b1f2be98fa
6 changed files with 77 additions and 12 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <SDL.h>
|
||||
|
||||
#include "cpu.hpp"
|
||||
#include "io_file.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "opengl.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
|
@ -43,6 +44,12 @@ public:
|
|||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
|
||||
// Get path for saving files (AppData on Windows, /home/user/.local/share/ApplcationName on Linux, etc)
|
||||
char* appData = SDL_GetPrefPath(nullptr, "Alber");
|
||||
IOFile::setAppDataDir(appData);
|
||||
SDL_free(appData);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include "helpers.hpp"
|
||||
#include "memory.hpp"
|
||||
|
@ -93,6 +95,51 @@ protected:
|
|||
using Handle = u32;
|
||||
Memory& mem;
|
||||
|
||||
// Returns if a specified 3DS path in UTF16 or ASCII format is safe or not
|
||||
// A 3DS path is considered safe if its first character is '/' which means we're not trying to access anything outside the root of the fs
|
||||
// And if it doesn't contain enough instances of ".." (Indicating "climb up a folder" in filesystems) to let the software climb up the directory tree
|
||||
// And access files outside of the emulator's app data folder
|
||||
template <u32 format>
|
||||
bool isPathSafe(const FSPath& path) {
|
||||
static_assert(format == PathType::ASCII || format == PathType::UTF16);
|
||||
using String = std::conditional<format == PathType::UTF16, std::u16string, std::string>::type; // String type for the path
|
||||
using Char = String::value_type; // Char type for the path
|
||||
|
||||
String pathString, dots;
|
||||
if constexpr (std::is_same<String, std::u16string>()) {
|
||||
pathString = path.utf16_string;
|
||||
dots = u"..";
|
||||
} else {
|
||||
pathString = path.string;
|
||||
dots = "..";
|
||||
}
|
||||
|
||||
// If the path string doesn't begin with / then that means it's accessing outside the FS root, which is invalid & unsafe
|
||||
if (pathString[0] != Char('/')) return false;
|
||||
|
||||
// Counts how many folders sans the root our file is nested under.
|
||||
// If it's < 0 at any point of parsing, then the path is unsafe and tries to crawl outside our file sandbox.
|
||||
// If it's 0 then this is the FS root.
|
||||
// If it's > 0 then we're in a subdirectory of the root.
|
||||
int level = 0;
|
||||
|
||||
// Split the string on / characters and see how many of the substrings are ".."
|
||||
size_t pos = 0;
|
||||
while ((pos = pathString.find(Char('/'))) != String::npos) {
|
||||
String token = pathString.substr(0, pos);
|
||||
pathString.erase(0, pos + 1);
|
||||
|
||||
if (token == dots) {
|
||||
level--;
|
||||
if (level < 0) return false;
|
||||
} else {
|
||||
level++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual std::string name() = 0;
|
||||
virtual u64 getFreeBytes() = 0;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
class IOFile {
|
||||
FILE* handle = nullptr;
|
||||
static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows
|
||||
|
||||
public:
|
||||
bool isOpen() {
|
||||
|
@ -81,4 +82,11 @@ public:
|
|||
bool rewind() {
|
||||
return seek(0, SEEK_SET);
|
||||
}
|
||||
|
||||
static void setAppDataDir(const char* dir) {
|
||||
if (!dir) Helpers::panic("Failed to set app data directory");
|
||||
appData = std::filesystem::path(dir);
|
||||
}
|
||||
|
||||
static std::filesystem::path getAppData() { return IOFile::appData; }
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue