Skip to content

Commit 4d6d8b5

Browse files
authored
Merge pull request #6 from x1nixmzeng/skip-invalid
Ignore invalid tree entries, as reported by #2
2 parents 70adb6f + e8c24b7 commit 4d6d8b5

File tree

3 files changed

+77
-48
lines changed

3 files changed

+77
-48
lines changed

src/vfs.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ SetupState Container::setup(const std::wstring &filename) {
1919

2020
if (!vd.validate()) {
2121
// Some "dual layer" ISO files will have both a video and game partition
22-
constexpr static size_t sc_gamePartitionOffset = 2048 * 32 * 6192;
22+
constexpr static size_t sc_gamePartitionOffset =
23+
xdvdfs::SECTOR_SIZE * 32 * 6192;
2324

2425
stream->m_offset = sc_gamePartitionOffset;
2526

@@ -82,7 +83,6 @@ Container::getFolderList(const std::filesystem::path &path) const {
8283
}
8384

8485
void Container::build(xdvdfs::Stream &file, xdvdfs::FileEntry &dirent) {
85-
// TODO consider std::filesystem::path::preferred_separator
8686
xdvdfs::FileEntry root("\\");
8787
auto newHandle = registerFileEntry(root, sc_invalidHandle);
8888

@@ -96,17 +96,24 @@ void Container::buildFromTreeRecursive(xdvdfs::Stream &file,
9696

9797
if (dirent.isDirectory()) {
9898
xdvdfs::FileEntry entry = dirent.getFirstEntry(file);
99-
buildFromTreeRecursive(file, entry, newHandle);
99+
if (entry.validate()) {
100+
buildFromTreeRecursive(file, entry, newHandle);
101+
}
100102
}
101103

102104
if (dirent.hasLeftChild()) {
103105
xdvdfs::FileEntry entry = dirent.getLeftChild(file);
104-
buildFromTreeRecursive(file, entry, parent);
106+
107+
if (entry.validate()) {
108+
buildFromTreeRecursive(file, entry, parent);
109+
}
105110
}
106111

107112
if (dirent.hasRightChild()) {
108113
xdvdfs::FileEntry entry = dirent.getRightChild(file);
109-
buildFromTreeRecursive(file, entry, parent);
114+
if (entry.validate()) {
115+
buildFromTreeRecursive(file, entry, parent);
116+
}
110117
}
111118
}
112119

src/xdvdfs.cc

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,28 @@
77
#include <vector>
88

99
namespace xdvdfs {
10-
bool VolumeDescriptor::validate() {
10+
void VolumeDescriptor::readFromFile(Stream &file) {
11+
std::vector<char> buffer(SECTOR_SIZE);
12+
13+
{
14+
std::lock_guard<std::mutex> lock(file.m_fileMutex);
15+
16+
file.m_file.seekg(VOLUME_DESCRIPTOR_SECTOR * SECTOR_SIZE + file.m_offset,
17+
std::ifstream::beg);
18+
file.m_file.read(buffer.data(), buffer.size());
19+
}
20+
21+
std::copy(buffer.begin(), buffer.begin() + 0x14, m_id1);
22+
std::copy(buffer.begin() + 0x14, buffer.begin() + 0x18,
23+
reinterpret_cast<char *>(&m_rootDirTableSector));
24+
std::copy(buffer.begin() + 0x18, buffer.begin() + 0x1C,
25+
reinterpret_cast<char *>(&m_rootDirTableSize));
26+
std::copy(buffer.begin() + 0x1C, buffer.begin() + 0x24,
27+
reinterpret_cast<char *>(&m_filetime));
28+
std::copy(buffer.begin() + 0x7EC, buffer.end(), m_id2);
29+
}
30+
31+
bool VolumeDescriptor::validate() const {
1132
if (std::memcmp(m_id1, MAGIC_ID, std::size(m_id1)) != 0) {
1233
return false;
1334
}
@@ -23,48 +44,26 @@ bool VolumeDescriptor::validate() {
2344
return true;
2445
}
2546

26-
FileEntry::FileEntry(const FileEntry &other)
27-
: m_leftSubTree(other.m_leftSubTree), m_rightSubTree(other.m_rightSubTree),
28-
m_startSector(other.m_startSector), m_fileSize(other.m_fileSize),
29-
m_attributes(other.m_attributes), m_filename(other.m_filename),
30-
m_sectorNumber(other.m_sectorNumber) {}
31-
32-
FileEntry::FileEntry(const std::string &name)
33-
: m_leftSubTree(0), m_rightSubTree(0), m_startSector(0), m_fileSize(0),
34-
m_attributes(FileEntry::FILE_DIRECTORY), m_filename(name),
35-
m_sectorNumber(0) {}
36-
37-
FileEntry VolumeDescriptor::getRootDirEntry(Stream &file) {
47+
FileEntry VolumeDescriptor::getRootDirEntry(Stream &file) const {
3848
FileEntry dirent;
3949

4050
dirent.readFromFile(file, m_rootDirTableSector, 0);
4151

4252
return dirent;
4353
}
54+
} // namespace xdvdfs
4455

45-
void VolumeDescriptor::readFromFile(Stream &file) {
46-
std::vector<char> buffer(SECTOR_SIZE);
47-
48-
{
49-
std::lock_guard<std::mutex> lock(file.m_fileMutex);
56+
namespace xdvdfs {
5057

51-
file.m_file.seekg(VOLUME_DESCRIPTOR_SECTOR * SECTOR_SIZE + file.m_offset,
52-
std::ifstream::beg);
53-
file.m_file.read(buffer.data(), buffer.size());
54-
}
58+
FileEntry::FileEntry(const FileEntry &other)
59+
: m_leftSubTree(other.m_leftSubTree), m_rightSubTree(other.m_rightSubTree),
60+
m_startSector(other.m_startSector), m_fileSize(other.m_fileSize),
61+
m_attributes(other.m_attributes), m_filename(other.m_filename),
62+
m_sectorNumber(other.m_sectorNumber) {}
5563

56-
std::copy(buffer.begin(), buffer.begin() + 0x14, m_id1);
57-
std::copy(buffer.begin() + 0x14, buffer.begin() + 0x18,
58-
reinterpret_cast<char *>(&m_rootDirTableSector));
59-
std::copy(buffer.begin() + 0x18, buffer.begin() + 0x1C,
60-
reinterpret_cast<char *>(&m_rootDirTableSize));
61-
std::copy(buffer.begin() + 0x1C, buffer.begin() + 0x24,
62-
reinterpret_cast<char *>(&m_filetime));
63-
std::copy(buffer.begin() + 0x7EC, buffer.end(), m_id2);
64-
}
65-
} // namespace xdvdfs
64+
FileEntry::FileEntry(const std::string &name)
65+
: m_attributes(FileEntry::FILE_DIRECTORY), m_filename(name) {}
6666

67-
namespace xdvdfs {
6867
void FileEntry::readFromFile(Stream &file, std::streampos sector,
6968
std::streamoff offset) {
7069
std::vector<char> buffer(SECTOR_SIZE);
@@ -77,6 +76,8 @@ void FileEntry::readFromFile(Stream &file, std::streampos sector,
7776
file.m_file.read(buffer.data(), buffer.size());
7877
}
7978

79+
m_sectorNumber = sector;
80+
8081
std::copy(buffer.begin(), buffer.begin() + 0x02,
8182
reinterpret_cast<char *>(&m_leftSubTree));
8283
std::copy(buffer.begin() + 0x02, buffer.begin() + 0x04,
@@ -88,10 +89,11 @@ void FileEntry::readFromFile(Stream &file, std::streampos sector,
8889
std::copy(buffer.begin() + 0x0C, buffer.begin() + 0x0D,
8990
reinterpret_cast<char *>(&m_attributes));
9091

91-
size_t filenameLength = buffer[0x0D];
92-
m_filename = std::string(&buffer[0x0E], filenameLength);
92+
if (validate()) {
93+
size_t filenameLength{static_cast<uint8_t>(buffer[0x0D])};
9394

94-
m_sectorNumber = sector;
95+
m_filename = std::string(&buffer[0x0E], filenameLength);
96+
}
9597
}
9698

9799
const std::string &FileEntry::getFilename() const { return m_filename; }
@@ -128,6 +130,22 @@ uint32_t FileEntry::read(Stream &file, void *buffer, uint32_t bufferlength,
128130
return 0;
129131
}
130132

133+
bool FileEntry::validate() const {
134+
if (m_leftSubTree == static_cast<uint16_t>(-1)) {
135+
return false;
136+
}
137+
138+
if (m_rightSubTree == static_cast<uint16_t>(-1)) {
139+
return false;
140+
}
141+
142+
if (m_startSector == static_cast<uint32_t>(-1)) {
143+
return false;
144+
}
145+
146+
return true;
147+
}
148+
131149
bool FileEntry::isDirectory() const {
132150
return ((m_attributes & FileEntry::FILE_DIRECTORY) != 0);
133151
}

src/xdvdfs.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ class FileEntry {
2727
FileEntry(const FileEntry &other);
2828
FileEntry(const std::string &name);
2929

30-
void readFromFile(Stream &file, std::streampos pos, std::streamoff offset);
31-
const std::string &getFilename() const;
32-
uint32_t getFileSize() const;
30+
void readFromFile(Stream &file, std::streampos sector, std::streamoff offset);
3331

3432
// matching dokany api for now
3533
uint32_t read(Stream &file, void *buffer, uint32_t bufferlength,
3634
int64_t offset) const;
3735

36+
bool validate() const;
37+
38+
const std::string &getFilename() const;
39+
uint32_t getFileSize() const;
40+
3841
uint8_t getAttributes() const { return m_attributes; }
3942
bool isDirectory() const;
4043
bool hasLeftChild() const;
@@ -52,8 +55,8 @@ class FileEntry {
5255
static const uint8_t FILE_NORMAL = 0x80;
5356

5457
private:
55-
uint16_t m_leftSubTree{0};
56-
uint16_t m_rightSubTree{0};
58+
uint16_t m_leftSubTree{static_cast<uint16_t>(-1)};
59+
uint16_t m_rightSubTree{static_cast<uint16_t>(-1)};
5760
uint32_t m_startSector{0};
5861
uint32_t m_fileSize{0};
5962
uint8_t m_attributes{0};
@@ -66,8 +69,9 @@ class VolumeDescriptor {
6669
public:
6770
void readFromFile(Stream &file);
6871

69-
bool validate();
70-
FileEntry getRootDirEntry(Stream &file);
72+
bool validate() const;
73+
74+
FileEntry getRootDirEntry(Stream &file) const;
7175
uint64_t getCreationTime() const { return m_filetime; }
7276

7377
protected:

0 commit comments

Comments
 (0)