Files
ppsspp/Core/Util/PathUtil.h
T
499cdd55ad Validate untrusted IDs before using them as directory names
Texture pack installs took the destination directory from the archive's
textures.ini, and PKG update installs from the PBOOT's DISC_ID, both
unchecked, so a crafted archive or package could write outside
PSP/TEXTURES or PSP/GAME. Add IsSafePathComponent() to PathUtil and check
both, replacing the WebServer's own upload filename check with it too.

DISC_ID from any PARAM.SFO also names configs, cheats, textures, exdata
and savestates, so ReadSFO now drops one that isn't a safe name and the
game gets a fake ID like homebrew. The same goes for a frame dump's ID.

Combines #22419 and #22420 by Acts1631.

Co-Authored-By: Acts1631 <acts1631kjv@proton.me>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:39:06 -06:00

56 lines
1.9 KiB
C++

#pragma once
#include <string>
#include <string_view>
#include "Common/File/Path.h"
// Use these in conjunction with GetSysDirectory.
enum PSPDirectories {
DIRECTORY_PSP,
DIRECTORY_CHEATS,
DIRECTORY_SCREENSHOT,
DIRECTORY_SYSTEM,
DIRECTORY_NAND,
DIRECTORY_GAME,
DIRECTORY_SAVEDATA,
DIRECTORY_PAUTH,
DIRECTORY_DUMP,
DIRECTORY_SAVESTATE,
DIRECTORY_CACHE,
DIRECTORY_TEXTURES,
DIRECTORY_PLUGINS,
DIRECTORY_APP_CACHE, // Use the OS app cache if available
DIRECTORY_VIDEO,
DIRECTORY_AUDIO,
DIRECTORY_MEMSTICK_ROOT,
DIRECTORY_EXDATA,
DIRECTORY_CUSTOM_SHADERS,
DIRECTORY_CUSTOM_THEMES,
COUNT,
};
// Returns true if the given path (e.g. a zip entry name) contains a parent
// directory ("..") component. Used to guard against path traversal when
// extracting or writing files to disk.
bool HasParentDirComponent(std::string_view path);
// Returns true if the given string contains a path separator ('/' or '\\')
// or is a bare dot component ("." or ".."). Used to reject guest-controlled
// strings that would otherwise become host filesystem path components.
bool HasPathTraversal(std::string_view path);
// Returns true if an untrusted string (a disc ID, a texture pack's game ID) can be used as a single
// directory or file name. Stricter than HasPathTraversal: also rejects empty names, control
// characters, ':' (drive letters, NTFS streams) and the trailing dots and spaces Win32 strips,
// which would turn "..." into "..".
bool IsSafePathComponent(std::string_view name);
Path FindConfigFile(const Path &searchPath, std::string_view baseFilename, bool *exists);
Path GetSysDirectory(PSPDirectories directoryType);
bool CreateSysDirectories();
Path GetGameConfigFilePath(const Path &searchPath, std::string_view gameId, bool *exists);
bool TryUpdateSavedPath(Path *path);
Path GetFailedBackendsDir();
std::string GetFriendlyPath(Path path, const Path &rootMatch = Path(), std::string_view rootDisplay = "ms:/");