fix(format): locate the address in version-1 shared messages
A version-1 shared message reference is version, type, six reserved bytes and then an old-style symbol table entry: link-name offset (length size), object header address, cache type, reserved, scratch. We read the address straight after the reserved bytes, i.e. the link-name offset, and the committed datatype lookup failed with InvalidObjectHeaderVersion (the bytes checked in tcompound.h5: name offset 0x10, then 0x590 = /type1). Datasets of 1.4/1.6-era files that use a committed datatype were unreadable. Skip the name offset. parse_shared_ref has no length size, so add parse_shared_ref_sized and use it in every internal caller; parse_shared_ref keeps its signature and assumes length size == offset size. The old parse_v1_ref unit test encoded the wrong layout and now uses the real bytes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -97,7 +97,7 @@ impl AttributeMessage {
|
||||
return Ok(Cow::Borrowed(bytes));
|
||||
}
|
||||
let (file_data, offset_size) = file.ok_or(FormatError::UnresolvedSharedMessage)?;
|
||||
let shared_ref = shared_message::parse_shared_ref(bytes, offset_size)?;
|
||||
let shared_ref = shared_message::parse_shared_ref_sized(bytes, offset_size, length_size)?;
|
||||
shared_message::resolve_shared_message(
|
||||
file_data,
|
||||
&shared_ref,
|
||||
@@ -407,7 +407,8 @@ pub fn extract_attributes_full(
|
||||
if msg.msg_type == MessageType::Attribute {
|
||||
if shared_message::is_shared(msg.flags) {
|
||||
// Shared attribute: resolve the reference to get actual attribute data
|
||||
let shared_ref = shared_message::parse_shared_ref(&msg.data, offset_size)?;
|
||||
let shared_ref =
|
||||
shared_message::parse_shared_ref_sized(&msg.data, offset_size, length_size)?;
|
||||
let resolved_data = shared_message::resolve_shared_message(
|
||||
file_data,
|
||||
&shared_ref,
|
||||
|
||||
Reference in New Issue
Block a user