From ee5025bb27862a7d2231911c08e1e0e1fa7dab20 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 2 Aug 2026 06:30:17 +0900 Subject: refactor(console-io): make ensure_valid_utf8 a no-op, drop iconv shim Rust's &str is always valid UTF-8, so the mbstring/iconv sanitization chain can never trigger. Reduce it to a no-op with a TODO(phase-c) marker: once the codebase strictly separates Vec from String, this should take &[u8] and convert lossily. This removes the last caller of the php-shim iconv(), so delete it as well. Co-Authored-By: Claude Fable 5 --- crates/shirabe-php-shim/src/string.rs | 18 ------------------ crates/shirabe/src/io/console_io.rs | 29 +++++------------------------ 2 files changed, 5 insertions(+), 42 deletions(-) diff --git a/crates/shirabe-php-shim/src/string.rs b/crates/shirabe-php-shim/src/string.rs index 28acb3bb..e0c84836 100644 --- a/crates/shirabe-php-shim/src/string.rs +++ b/crates/shirabe-php-shim/src/string.rs @@ -421,24 +421,6 @@ pub fn mb_convert_variables(_to: &str, _from: &str, _vars: &mut Vec) -> Some(_from.to_string()) } -pub fn iconv(_in_charset: &str, _out_charset: &str, _string: &str) -> Option { - let from = canonical_encoding(_in_charset); - // The output charset may carry a "//TRANSLIT" / "//IGNORE" suffix. - let to_base = _out_charset.split("//").next().unwrap_or(_out_charset); - let to = canonical_encoding(to_base); - // ASCII is a subset of UTF-8, so any conversion among ASCII/UTF-8 that targets UTF-8 is a - // byte-level no-op. - if to == "UTF-8" && matches!(from.as_str(), "UTF-8" | "ASCII") { - return Some(_string.to_string()); - } - if to == "ASCII" && from == "ASCII" { - return Some(_string.to_string()); - } - // TODO(phase-d): general iconv conversion needs encoding tables and //TRANSLIT///IGNORE handling - // for non-UTF-8 targets, which have not been ported yet. - todo!("iconv {} -> {}", from, to) -} - /// Resolve PHP array_slice/substr-style (offset, length) into a `[start, end)` /// pair of indices, honouring negative offsets and lengths. fn php_slice_bounds(len: i64, offset: i64, length: Option) -> (usize, usize) { diff --git a/crates/shirabe/src/io/console_io.rs b/crates/shirabe/src/io/console_io.rs index de6fdede..cf488855 100644 --- a/crates/shirabe/src/io/console_io.rs +++ b/crates/shirabe/src/io/console_io.rs @@ -7,7 +7,6 @@ use crate::io::IOInterfaceImmutable; use crate::io::IOInterfaceMutable; use crate::io::io_interface; use crate::question::StrictConfirmationQuestion; -use crate::util::Silencer; use indexmap::IndexMap; use indexmap::indexmap; use shirabe_external_packages::composer::pcre::Preg; @@ -25,8 +24,8 @@ use shirabe_external_packages::symfony::console::question::ChoiceQuestion; use shirabe_external_packages::symfony::console::question::Question; use shirabe_external_packages::symfony::console::question::QuestionInterface; use shirabe_php_shim::{ - PhpMixed, array_search, function_exists, implode, in_array, is_array, is_string, - mb_check_encoding, mb_convert_encoding, microtime, str_repeat, strip_tags, strlen, + PhpMixed, array_search, implode, in_array, is_array, is_string, microtime, str_repeat, + strip_tags, strlen, }; /// The Input/Output helper. @@ -313,28 +312,10 @@ impl ConsoleIO { } /// Ensures a string is valid UTF-8, replacing invalid byte sequences with '?' + // TODO(phase-c): PHP sanitizes invalid byte sequences here, but `&str` is always valid UTF-8 + // so this is a no-op for now. The codebase does not yet strictly distinguish `Vec` from + // `String`; once it does, this should take `&[u8]` and lossily convert it to `String`. fn ensure_valid_utf8(string: &str) -> String { - // Quick check: if string is already valid UTF-8, return as-is - if function_exists("mb_check_encoding") && mb_check_encoding(string, "UTF-8") { - return string.to_string(); - } - - // Use mb_convert_encoding to replace invalid sequences with '?' - // This makes it visible when data quality issues occur - if function_exists("mb_convert_encoding") { - return mb_convert_encoding(string.as_bytes().to_vec(), "UTF-8", "UTF-8"); - } - - // Fallback to iconv if mbstring unavailable - if function_exists("iconv") { - let cleaned = - Silencer::call(|| Ok(shirabe_php_shim::iconv("UTF-8", "UTF-8//TRANSLIT", string))); - if let Ok(Some(c)) = cleaned { - return c; - } - } - - // Last resort: return as-is (should never happen - Composer requires mbstring OR iconv) string.to_string() } -- cgit v1.3.1