Merge pull request #4504 from yunusshaikh7/fix/savedata-dir-name-trailing-wildcard
fix(savedata): let a trailing % in a directory name pattern match nothing
This commit is contained in:
commit
4756c051ef
|
|
@ -62,6 +62,9 @@ static bool dir_name_match(const char* str, const char* pattern) {
|
|||
str++;
|
||||
pattern++;
|
||||
}
|
||||
while (*pattern == '%') {
|
||||
pattern++;
|
||||
}
|
||||
return *str == '\0' && *pattern == '\0';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,31 @@ static void SortByKey() {
|
|||
Require(sceSaveDataDirNameSearch(&cond, &result) == SaveDataErrorParameter, "an unknown sort order must be rejected");
|
||||
}
|
||||
|
||||
static std::vector<std::string> SearchPattern(const char* text) {
|
||||
SceSaveDataDirName pattern{};
|
||||
std::snprintf(pattern.data, sizeof(pattern.data), "%s", text);
|
||||
SaveDataDirNameSearchCond cond{};
|
||||
cond.user_id = 1;
|
||||
cond.dir_name = &pattern;
|
||||
std::array<SceSaveDataDirName, 4> names{};
|
||||
SaveDataDirNameSearchResult result{};
|
||||
result.dir_names = names.data();
|
||||
result.dir_names_num = static_cast<std::uint32_t>(names.size());
|
||||
Require(sceSaveDataDirNameSearch(&cond, &result) == 0, "pattern search failed");
|
||||
std::vector<std::string> found;
|
||||
for (std::uint32_t i = 0; i < result.set_num; ++i) found.emplace_back(names[i].data);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void TrailingWildcards() {
|
||||
for (const char* name : std::array{"TRAIL", "TRAIL1"}) std::filesystem::create_directories(std::filesystem::path("_sd") / name);
|
||||
using Names = std::vector<std::string>;
|
||||
Require(SearchPattern("TRAIL%") == Names{"TRAIL", "TRAIL1"}, "a trailing % must also match no characters");
|
||||
Require(SearchPattern("TRAIL%%") == Names{"TRAIL", "TRAIL1"}, "trailing %% must also match no characters");
|
||||
Require(SearchPattern("TRAI_%") == Names{"TRAIL", "TRAIL1"}, "_ then % must match one character and then none");
|
||||
Require(SearchPattern("TRAIL_%") == Names{"TRAIL1"}, "_ must still match exactly one character");
|
||||
}
|
||||
|
||||
static void SearchAndMount() {
|
||||
const std::array names{std::string(31, 'A'), std::string(31, 'B')};
|
||||
for (const auto& name : names) std::filesystem::create_directories(std::filesystem::path("_sd") / name);
|
||||
|
|
@ -139,6 +164,7 @@ int main() {
|
|||
try {
|
||||
SearchAndMount();
|
||||
SortByKey();
|
||||
TrailingWildcards();
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
status = 1;
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceNgs2VoiceQueryInfo](../../core/libs/prx/libSceNgs2.native/src/Voice.cpp) (libSceNgs2.native) - only info id 0x4001 is known: PPSA22520 passes an 8-byte buffer and branches on the first word being 1 or 2, so it is assumed to be the voice channel count (0 before the voice is set up); the second word is zeroed and other ids throw
|
||||
- [sceNgs2VoiceGetPortInfo](../../core/libs/prx/libSceNgs2.native/src/Voice.cpp) (libSceNgs2.native) - layout from shadPS4; the delay and destination input are zero because ports have neither yet
|
||||
- [sceNgs2ParseWaveformFile](../../core/libs/prx/libSceNgs2.native/src/Atrac9.cpp) (libSceNgs2.native) - the signature `(path, offset, info)` is taken from the call site of PPSA21402, which sets only three argument registers; the file is read from `offset` to its end, the data and block offsets are taken to be relative to the start of the file, not of `offset`, and an unreadable file throws. The audio unit fields of a 16-bit PCM waveform are assumed to be one sample frame per unit and per frame; `INVALID_WAVEFORM_DATA` for a `data` chunk that runs past the buffer or ends inside a frame is assumed, and looped PCM and other PCM formats throw
|
||||
- [sceSaveDataDirNameSearch](../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native) - the sort keys (0 directory name, 1 user parameter, 2 blocks, 3 modification time, 5 free blocks) and orders (0 ascending, 1 descending) follow shadPS4, not a hardware run; saves with equal keys keep directory-name order before a descending reverse. Every native save reports `SAVE_DATA_BLOCKS_MAX` blocks, as `sceSaveDataGetMountInfo` does, so the two block keys keep directory-name order. The search infos (blocks, free blocks and 32 reserved bytes per returned name, following shadPS4's `OrbisSaveDataSearchInfo`) report `SAVE_DATA_BLOCKS_MAX` for both. Keys other than 0, 1, 2, 3 and 5 (including 4) and orders above 1 return `SCE_SAVE_DATA_ERROR_PARAMETER`; shadPS4 and KytyPS5 only reject keys above 5, so key 4 is rejected here because no source names it
|
||||
- [sceSaveDataDirNameSearch](../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native) - the sort keys (0 directory name, 1 user parameter, 2 blocks, 3 modification time, 5 free blocks) and orders (0 ascending, 1 descending) follow shadPS4, not a hardware run; saves with equal keys keep directory-name order before a descending reverse. Every native save reports `SAVE_DATA_BLOCKS_MAX` blocks, as `sceSaveDataGetMountInfo` does, so the two block keys keep directory-name order. The search infos (blocks, free blocks and 32 reserved bytes per returned name, following shadPS4's `OrbisSaveDataSearchInfo`) report `SAVE_DATA_BLOCKS_MAX` for both. Keys other than 0, 1, 2, 3 and 5 (including 4) and orders above 1 return `SCE_SAVE_DATA_ERROR_PARAMETER`; shadPS4 and KytyPS5 only reject keys above 5, so key 4 is rejected here because no source names it. In the directory name pattern `%` matches any run of characters, none included, and `_` exactly one, as the comments of shadPS4's matcher describe; also not confirmed on hardware
|
||||
- [sceSaveDataInitialize3](../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native) - a repeated initialize succeeds: PPSA12544's executable and its Unity SaveData plugin both initialize, and the plugin fails on any error. Initializations are counted and `sceSaveDataTerminate` ends the session at the last one; how the console pairs them is unknown
|
||||
- [sceTextToSpeech2GetSystemStatus](../../core/libs/prx/libSceTextToSpeech2/Export.cpp) (libSceTextToSpeech2) - unknown signature; returns `EOPNOTSUPP` like `sceTextToSpeech2Initialize`
|
||||
- [sceCoredumpAttachUserMemoryFile](../../core/libs/prx/libkernel/System/src/Coredump.cpp) (libkernel) - unknown signature
|
||||
|
|
|
|||
Loading…
Reference in New Issue