From 87151010ed4d7b23b2673cb349cf0871dba8dc9c Mon Sep 17 00:00:00 2001 From: Oleksandr Kozachuk Date: Wed, 8 Apr 2026 13:02:05 +0200 Subject: [PATCH] Fix S\" escape sequences corrupted by UTF-8 lossy conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parse_s_escape returned String via from_utf8_lossy which replaces non-UTF-8 bytes (like \xAB = 171) with the 3-byte U+FFFD replacement character, corrupting both string length and content. Changed to return Vec and write raw bytes directly to WASM memory. Also registered ( as immediate word for FIND, added 'x' char literals. Core_ext: 14→8 errors. --- crates/core/src/outer.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/crates/core/src/outer.rs b/crates/core/src/outer.rs index 8fad281..f518974 100644 --- a/crates/core/src/outer.rs +++ b/crates/core/src/outer.rs @@ -597,13 +597,12 @@ impl ForthVM { } if token_upper == "S\\\"" { // S\" with escape sequences in interpret mode - if let Some(s) = self.parse_s_escape() { + if let Some(raw) = self.parse_s_escape() { self.refresh_user_here(); let addr = self.user_here; - let bytes = s.as_bytes(); - let len = bytes.len() as u32; + let len = raw.len() as u32; let data = self.memory.data_mut(&mut self.store); - data[addr as usize..addr as usize + len as usize].copy_from_slice(bytes); + data[addr as usize..addr as usize + len as usize].copy_from_slice(&raw); self.user_here += len; self.sync_here_cell(); self.push_data_stack(addr as i32)?; @@ -978,13 +977,12 @@ impl ForthVM { } "S\\\"" => { // S\" with escape sequences - if let Some(s) = self.parse_s_escape() { + if let Some(raw) = self.parse_s_escape() { self.refresh_user_here(); let addr = self.user_here; - let bytes = s.as_bytes(); - let len = bytes.len() as u32; + let len = raw.len() as u32; let data = self.memory.data_mut(&mut self.store); - data[addr as usize..addr as usize + len as usize].copy_from_slice(bytes); + data[addr as usize..addr as usize + len as usize].copy_from_slice(&raw); self.user_here += len; self.sync_here_cell(); self.push_ir(IrOp::PushI32(addr as i32)); @@ -2865,7 +2863,7 @@ impl ForthVM { } /// Parse a string with escape sequences for S\". - fn parse_s_escape(&mut self) -> Option { + fn parse_s_escape(&mut self) -> Option> { let bytes = self.input_buffer.as_bytes(); // Skip one leading space if present if self.input_pos < bytes.len() && bytes[self.input_pos] == b' ' { @@ -2924,7 +2922,7 @@ impl ForthVM { if self.input_pos < bytes.len() { self.input_pos += 1; } - Some(String::from_utf8_lossy(&result).to_string()) + Some(result) } // -----------------------------------------------------------------------