Skip to content

Commit

Permalink
Iterate through siblings without recursion in vfs::TraverseDirectory (
Browse files Browse the repository at this point in the history
strato-emu#205)

Prevents a stack overflow because of recursion depth.
  • Loading branch information
PabloG02 authored Jan 5, 2024
1 parent 3fb7f9b commit 1323259
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions app/src/main/cpp/skyline/vfs/rom_filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,27 @@ namespace skyline::vfs {
}

void RomFileSystem::TraverseDirectory(u32 offset, const std::string &path) {
auto entry{backing->Read<RomFsDirectoryEntry>(header.dirMetaTableOffset + offset)};
RomFsDirectoryEntry entry;
do {
entry = backing->Read<RomFsDirectoryEntry>(header.dirMetaTableOffset + offset);

std::string childPath(path);
if (entry.nameSize) {
std::vector<char> name(entry.nameSize);
backing->Read(span(name), header.dirMetaTableOffset + offset + sizeof(RomFsDirectoryEntry));
childPath = path + (path.empty() ? "" : "/") + std::string(name.data(), entry.nameSize);
}
std::string childPath(path);
if (entry.nameSize) {
std::vector<char> name(entry.nameSize);
backing->Read(span(name), header.dirMetaTableOffset + offset + sizeof(RomFsDirectoryEntry));
childPath = path + (path.empty() ? "" : "/") + std::string(name.data(), entry.nameSize);
}

directoryMap.emplace(childPath, entry);
directoryMap.emplace(childPath, entry);

if (entry.fileOffset != constant::RomFsEmptyEntry)
TraverseFiles(entry.fileOffset, childPath);
if (entry.fileOffset != constant::RomFsEmptyEntry)
TraverseFiles(entry.fileOffset, childPath);

if (entry.childOffset != constant::RomFsEmptyEntry)
TraverseDirectory(entry.childOffset, childPath);
if (entry.childOffset != constant::RomFsEmptyEntry)
TraverseDirectory(entry.childOffset, childPath);

if (entry.siblingOffset != constant::RomFsEmptyEntry)
TraverseDirectory(entry.siblingOffset, path);
offset = entry.siblingOffset;
} while (entry.siblingOffset != constant::RomFsEmptyEntry);
}

std::shared_ptr<Backing> RomFileSystem::OpenFileImpl(const std::string &path, Backing::Mode mode) {
Expand Down

0 comments on commit 1323259

Please sign in to comment.