Fixed crash at boot parsing an ISO with a empty directory entry at file head

This commit is contained in:
digant73 2026-04-04 01:08:55 +02:00
parent c613aca2c4
commit 2fa716445c
2 changed files with 18 additions and 12 deletions

View File

@ -388,8 +388,8 @@ inline T read_both_endian_int(fs::file& file)
return out;
}
// assumed that directory_entry is at file head
std::optional<iso_fs_metadata> iso_read_directory_entry(fs::file& file, bool names_in_ucs2 = false)
// Assumed that directory entry is at file head
static std::optional<iso_fs_metadata> iso_read_directory_entry(fs::file& file, bool names_in_ucs2 = false)
{
const auto start_pos = file.pos();
const u8 entry_length = file.read<u8>();
@ -489,7 +489,7 @@ static void iso_form_hierarchy(fs::file& file, iso_fs_node& node, bool use_ucs2_
// Assuming the directory spans a single extent
const auto& directory_extent = node.metadata.extents[0];
const u64 end_pos = directory_extent.size + (directory_extent.start * ISO_SECTOR_SIZE);
const u64 end_pos = (directory_extent.start * ISO_SECTOR_SIZE) + directory_extent.size;
file.seek(directory_extent.start * ISO_SECTOR_SIZE);
@ -586,10 +586,15 @@ iso_archive::iso_archive(const std::string& path)
// Skip the rest of descriptor's data
m_file.seek(155, fs::seek_cur);
m_root = iso_fs_node
const auto node = iso_read_directory_entry(m_file, use_ucs2_decoding);
if (node)
{
.metadata = iso_read_directory_entry(m_file, use_ucs2_decoding).value(),
};
m_root = iso_fs_node
{
.metadata = node.value()
};
}
}
m_file.seek(descriptor_start + ISO_SECTOR_SIZE);
@ -696,7 +701,7 @@ psf::registry iso_archive::open_psf(const std::string& path)
iso_file::iso_file(fs::file&& iso_handle, std::shared_ptr<iso_file_decryption> iso_dec, const iso_fs_node& node)
: m_file(std::move(iso_handle)), m_dec(iso_dec), m_meta(node.metadata)
{
m_file.seek(ISO_SECTOR_SIZE * node.metadata.extents[0].start);
m_file.seek(node.metadata.extents[0].start * ISO_SECTOR_SIZE);
}
fs::stat_t iso_file::get_stat()
@ -791,9 +796,10 @@ u64 iso_file::read_at(u64 offset, void* buffer, u64 size)
// IMPORTANT NOTE:
//
// For performance reasons, current "iso_file_decryption::decrypt()" method requires that reads always start at the beginning of a sector and
// that all reads will be multiples of ISO_SECTOR_SIZE.
// Both are easy fixes, but, code can be more simple + efficient if these two conditions are true (which they look to be from initial testing)
// For performance reasons, current "iso_file_decryption::decrypt()" method requires that reads always
// start at the beginning of a sector and that all reads will be multiples of ISO_SECTOR_SIZE.
// Both are easy fixes, but, code can be more simple + efficient if these two conditions are true
// (which they look to be from initial testing)
//
//
// TODO:

View File

@ -14,7 +14,7 @@ void unload_iso();
/*
- Hijacked the "iso_archive::iso_archive" method to test if the ".iso" file is encrypted and sets a flag.
The flag is set according to the first matching encryption type in the order below:
The flag is set according to the first matching encryption type found in the following order:
- Redump type: ".dkey" file, with the same name of the ".iso" file, exists in the same folder of the ".iso" file
- 3k3y type: 3k3y watermark exists at 0xF70
If the flag is set then the "iso_file::read" method will decrypt the data on the fly
@ -94,7 +94,7 @@ class iso_file : public fs::file_base
private:
fs::file m_file;
std::shared_ptr<iso_file_decryption> m_dec;
iso_fs_metadata m_meta {};
iso_fs_metadata m_meta;
u64 m_pos = 0;
std::pair<u64, iso_extent_info> get_extent_pos(u64 pos) const;