Bound infrastructure payload string fallbacks
This commit is contained in:
parent
ae67719ac6
commit
1873db0b08
3 changed files with 51 additions and 33 deletions
|
|
@ -3966,6 +3966,7 @@ fn build_infrastructure_asset_trace_report(
|
|||
"direct disassembly now also shows 0x00493be0 iterating live-entry ordinals through 0x00518380(ordinal, 0), converting each ordinal to a live id, then resolving that live id through 0x00518140 before handing the resulting payload pointer to 0x0048dcf0".to_string(),
|
||||
"direct disassembly now shows 0x00518680 loading the non-direct collection header, tombstone bitset, and live-id-bound-scaled 12-byte tables for the non-direct path before 0x00493be0 starts iterating".to_string(),
|
||||
"direct disassembly now also shows the shared child payload callback 0x00455fc0 opening 0x55f1, parsing three len-prefixed strings through 0x531380, opening 0x55f2, seeding the child through 0x455b70, dispatching slot +0x48, and then opening 0x55f3".to_string(),
|
||||
"direct disassembly now also shows 0x00455b70 storing those three payload strings into [this+0x206/+0x20a/+0x20e], defaulting the second lane through a fixed literal when absent and defaulting the third lane back to the first string when absent".to_string(),
|
||||
format!(
|
||||
"current save-side probe reports {} embedded 0x55f1 rows with a third decoded string",
|
||||
side_buffer
|
||||
|
|
@ -3980,7 +3981,6 @@ fn build_infrastructure_asset_trace_report(
|
|||
blockers: vec![
|
||||
"how the payload streams reached through 0x00518380 -> 0x00518140 align with the embedded 0x55f1 name-pair groups and compact-prefix regimes surfaced by the save-side probe".to_string(),
|
||||
"which tagged values inside each payload stream correspond to the child count, optional primary-child ordinal, and the per-child shared tagged callback sequence consumed by 0x0048dcf0".to_string(),
|
||||
"whether the third 0x55f1 string parsed by 0x00455fc0 is absent on grounded saves, stored under a different framing than the current probe, or only populated on a narrower infrastructure subset".to_string(),
|
||||
"which restored child fields or grouped rows retain the 0x38a5 embedded name-pair semantics before route/local-runtime follow-ons take over".to_string(),
|
||||
],
|
||||
},
|
||||
|
|
@ -12546,6 +12546,26 @@ fn parse_save_len_prefixed_ascii_name(bytes: &[u8]) -> Option<String> {
|
|||
Some(text.to_string())
|
||||
}
|
||||
|
||||
fn parse_save_varlen_ascii_name_at(bytes: &[u8], offset: usize) -> Option<(String, usize)> {
|
||||
let first = *bytes.get(offset)?;
|
||||
if first == 0 {
|
||||
return None;
|
||||
}
|
||||
let (len, header_len) = if first <= 0x7f {
|
||||
(first as usize, 1usize)
|
||||
} else {
|
||||
let second = *bytes.get(offset + 1)? as usize;
|
||||
((((first as usize) & 0x7f) << 8) | second, 2usize)
|
||||
};
|
||||
let start = offset + header_len;
|
||||
let end = start.checked_add(len)?;
|
||||
let text = std::str::from_utf8(bytes.get(start..end)?)
|
||||
.ok()?
|
||||
.trim_end_matches('\0')
|
||||
.to_string();
|
||||
Some((text, end))
|
||||
}
|
||||
|
||||
fn parse_save_len_prefixed_ascii_name_pair(bytes: &[u8]) -> Option<(String, String)> {
|
||||
let (first, second, _) = parse_save_len_prefixed_ascii_name_triplet(bytes)?;
|
||||
Some((first, second))
|
||||
|
|
@ -12554,42 +12574,22 @@ fn parse_save_len_prefixed_ascii_name_pair(bytes: &[u8]) -> Option<(String, Stri
|
|||
fn parse_save_len_prefixed_ascii_name_triplet(
|
||||
bytes: &[u8],
|
||||
) -> Option<(String, String, Option<String>)> {
|
||||
let first_len = *bytes.first()? as usize;
|
||||
let first_end = 1 + first_len;
|
||||
let first = std::str::from_utf8(bytes.get(1..first_end)?)
|
||||
.ok()?
|
||||
.trim_end_matches('\0')
|
||||
.to_string();
|
||||
let (first, first_end) = parse_save_varlen_ascii_name_at(bytes, 0)?;
|
||||
let mut second_len_offset = first_end;
|
||||
while matches!(bytes.get(second_len_offset), Some(0)) {
|
||||
second_len_offset += 1;
|
||||
}
|
||||
let second_len = *bytes.get(second_len_offset)? as usize;
|
||||
let second_start = second_len_offset + 1;
|
||||
let second = std::str::from_utf8(bytes.get(second_start..second_start + second_len)?)
|
||||
.ok()?
|
||||
.trim_end_matches('\0')
|
||||
.to_string();
|
||||
let (second, second_end) = parse_save_varlen_ascii_name_at(bytes, second_len_offset)?;
|
||||
if first.is_empty() || second.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut third_len_offset = second_start + second_len;
|
||||
let mut third_len_offset = second_end;
|
||||
while matches!(bytes.get(third_len_offset), Some(0)) {
|
||||
third_len_offset += 1;
|
||||
}
|
||||
let third = bytes
|
||||
.get(third_len_offset)
|
||||
.copied()
|
||||
.filter(|len| *len != 0)
|
||||
.and_then(|third_len| {
|
||||
let third_len = third_len as usize;
|
||||
let third_start = third_len_offset + 1;
|
||||
let text = std::str::from_utf8(bytes.get(third_start..third_start + third_len)?)
|
||||
.ok()?
|
||||
.trim_end_matches('\0')
|
||||
.to_string();
|
||||
(!text.is_empty()).then_some(text)
|
||||
});
|
||||
let third = parse_save_varlen_ascii_name_at(bytes, third_len_offset)
|
||||
.map(|(text, _)| text)
|
||||
.filter(|text| !text.is_empty());
|
||||
Some((first, second, third))
|
||||
}
|
||||
|
||||
|
|
@ -20409,6 +20409,18 @@ mod tests {
|
|||
assert_eq!(parsed.2.as_deref(), Some("Third"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_save_len_prefixed_ascii_name_triplet_with_extended_length_prefix() {
|
||||
let mut bytes = Vec::new();
|
||||
bytes.extend_from_slice(&[0x80, 0x03, b'A', b'B', b'C']);
|
||||
bytes.extend_from_slice(&[0, 1, b'X']);
|
||||
let parsed = parse_save_len_prefixed_ascii_name_triplet(&bytes)
|
||||
.expect("triplet parser should decode extended-length prefix");
|
||||
assert_eq!(parsed.0, "ABC");
|
||||
assert_eq!(parsed.1, "X");
|
||||
assert_eq!(parsed.2, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aligns_placed_structure_dynamic_side_buffer_name_pairs_with_triplets() {
|
||||
let side_buffer = SmpSavePlacedStructureDynamicSideBufferProbe {
|
||||
|
|
|
|||
|
|
@ -2937,9 +2937,12 @@ The low helper strip beneath that shared family is tighter now too: `0x0052ecd0`
|
|||
cached bridge bands, opens `0x55f1`, parses three len-prefixed strings through `0x00531380`,
|
||||
opens `0x55f2`, seeds the child through `0x00455b70`, dispatches slot `+0x48`, runs the local
|
||||
follow-on `0x0052ebd0`, and then opens `0x55f3`. The widened save-side probe currently still
|
||||
sees only two embedded `0x55f1` strings on grounded `q.gms`, so the remaining payload question is
|
||||
whether that third parsed string is absent on ordinary saves, hidden behind different framing, or
|
||||
only populated on a narrower infrastructure subset.
|
||||
sees only two embedded `0x55f1` strings on grounded `q.gms`, but `0x00455b70` now makes that
|
||||
result much less mysterious: it stores the three payload strings into `[this+0x206/+0x20a/+0x20e]`,
|
||||
defaulting the second lane through a fixed literal when absent and defaulting the third lane back
|
||||
to the first string when absent. So the remaining payload question is no longer “where is the
|
||||
third string hiding?”; it is how the current dual-name save-side rows align with the full
|
||||
payload-stream grouping and the later tagged value roles.
|
||||
The child loader family is explicit now too: local `.rdata` at `0x005cfd00` proves the
|
||||
`Infrastructure` child vtable uses the shared tagged callback strip directly, with
|
||||
`+0x40 = 0x00455fc0`, `+0x48 = 0x00455870`, and `+0x4c = 0x00455930`. So the remaining
|
||||
|
|
|
|||
|
|
@ -69,9 +69,12 @@ Working rule:
|
|||
disassembly now also shows the shared child payload callback `0x00455fc0` opening
|
||||
`0x55f1 -> 0x55f2 -> 0x55f3`, parsing three `0x55f1` strings through `0x00531380`, seeding the
|
||||
child through `0x00455b70`, and then dispatching slot `+0x48`; the widened save-side probe
|
||||
currently sees `0` third `0x55f1` strings on grounded `q.gms`, so the next pass should ask
|
||||
whether that third string is genuinely absent on ordinary saves or stored under different
|
||||
framing than the current embedded-row scan.
|
||||
currently sees `0` third `0x55f1` strings on grounded `q.gms`. That now looks less like a probe
|
||||
failure and more like an ordinary fallback path, because direct disassembly of `0x00455b70`
|
||||
stores the three payload strings into `[this+0x206/+0x20a/+0x20e]`, defaulting the second lane
|
||||
through a fixed literal when absent and defaulting the third lane back to the first string when
|
||||
absent. So the next pass should stay focused on payload-stream grouping and tagged value roles,
|
||||
not on rediscovering a missing third-string encoding.
|
||||
- The child loader identity is closed now too: local `.rdata` at `0x005cfd00` proves the
|
||||
`Infrastructure` child vtable uses the shared tagged callback strip directly, with
|
||||
`+0x40 = 0x00455fc0`, `+0x48 = 0x00455870`, and `+0x4c = 0x00455930`. So the remaining
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue