From 106590d1513cff3b155f51eda727919792e54321 Mon Sep 17 00:00:00 2001 From: hermes Date: Sun, 18 Oct 2026 11:56:25 +0000 Subject: [PATCH] fix(core): a row with no parsed cells rejects the page too Every piece of the table body that holds a row must parse as nine cells; ranks count the rows read, not the pieces. A rank-1 row without its cell ends was skipped and ranks 2-10 still matched (Codex re-review). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh --- crates/idx-core/src/api/ipot/parse.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/idx-core/src/api/ipot/parse.rs b/crates/idx-core/src/api/ipot/parse.rs index c996ff5..74763e9 100644 --- a/crates/idx-core/src/api/ipot/parse.rs +++ b/crates/idx-core/src/api/ipot/parse.rs @@ -176,12 +176,14 @@ pub fn parse_broker_summary(html: &str) -> Result { // another shape, a rank out of order, or a broker after a side's blank // rows rejects the page. let (mut buyers_ended, mut sellers_ended) = (false, false); - for (index, row) in html[body_start..body_end].split("").enumerate() { - let row = cells(row); - if row.is_empty() { + let mut rank = 0; + for piece in html[body_start..body_end].split("") { + // Only the space after the last row has no row in it. + if !piece.contains("().ok() != Some(rank) { return Err(IdxError::ParseError(format!( "ipot broker summary: unexpected row {rank} ({} cells, rank {:?})", @@ -349,7 +351,19 @@ mod tests { 1, ); let gap = DAY.replacen(">XL<", "><", 1); - for page in [short_row, skipped_rank, gap, "".to_string()] { + // Rank 1 without its cell ends parses to no cells at all. + let body = DAY.find("").unwrap(); + let first_row_end = body + DAY[body..].find("").unwrap(); + let unclosed = DAY[..body].to_string() + + &DAY[body..first_row_end].replace("", "") + + &DAY[first_row_end..]; + for page in [ + short_row, + skipped_rank, + gap, + unclosed, + "".to_string(), + ] { assert!( matches!(parse_broker_summary(&page), Err(IdxError::ParseError(_))), "{}",