From 0bba63d3032f1c83844b0c74befc133d27fa9464 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 12 Jan 2026 14:02:05 +0800 Subject: [PATCH] Use better way to detect bp script end instruction fix bgi dsc overflow in debug build --- src/scripts/bgi/archive/dsc.rs | 2 +- src/scripts/bgi/bp.rs | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/scripts/bgi/archive/dsc.rs b/src/scripts/bgi/archive/dsc.rs index bbe2e37..0b57db0 100644 --- a/src/scripts/bgi/archive/dsc.rs +++ b/src/scripts/bgi/archive/dsc.rs @@ -209,7 +209,7 @@ impl<'a> DscDecoder<'a> { .0 .overflowing_add(self.key.overflowing_mul(346).0) .0; - v1 = (v1 + (v0 >> 16)) & 0xffff; + v1 = overf::wrapping!(v1 + (v0 >> 16)) & 0xffff; self.key = (v1 << 16) + (v0 & 0xffff) + 1; v1 as u8 } diff --git a/src/scripts/bgi/bp.rs b/src/scripts/bgi/bp.rs index 097d6ac..04ef852 100644 --- a/src/scripts/bgi/bp.rs +++ b/src/scripts/bgi/bp.rs @@ -73,21 +73,29 @@ impl BGIBpScript { } let mut last_instr_pos = 0; reader.seek(SeekFrom::Start(header_size as u64))?; - let max_instr_len = reader.data.len() - 4; - let mut last_instr_is_valid = true; + let max_instr_len = reader.data.len(); while reader.pos < max_instr_len { - let instr = reader.cpeek_u32()?; + let instr = reader.peek_u8()?; if instr == 0x17 { - last_instr_pos = reader.pos; - reader.pos += 4; - } else { - reader.pos += 1; + let need_zero_bytes = 3 - reader.pos % 4; + let mut all_zero = true; + for i in 0..need_zero_bytes { + let b = reader.peek_u8_at(reader.pos as u64 + 1 + i as u64)?; + if b != 0 { + all_zero = false; + break; + } + } + if all_zero { + last_instr_pos = reader.pos; + reader.pos += 1 + need_zero_bytes; + continue; + } } + reader.pos += 1; } if last_instr_pos == 0 { - // return Err(anyhow::anyhow!("No end instruction found in bp script")); - last_instr_pos = reader.data.len(); - last_instr_is_valid = false; + return Err(anyhow::anyhow!("No end instruction found in bp script")); } reader.seek(SeekFrom::Start(header_size as u64))?; let mut strings = Vec::new(); @@ -96,7 +104,7 @@ impl BGIBpScript { if ins == 5 { let text_offset = reader.peek_u16()?; let text_address = reader.pos + text_offset as usize - 1; - if (text_address >= last_instr_pos || !last_instr_is_valid) + if text_address >= last_instr_pos && text_address < reader.data.len() && (text_address == last_instr_pos || reader.data[text_address - 1] == 0) {