Analyzer安定化完了: NYASH_DISABLE_PLUGINS=1復元 + plugin無効化根治

## 修正内容
1. **hako_check.sh/run_tests.sh**: NYASH_DISABLE_PLUGINS=1 + NYASH_BOX_FACTORY_POLICY=builtin_first追加
2. **src/box_factory/plugin.rs**: NYASH_DISABLE_PLUGINS=1チェック追加
3. **src/box_factory/mod.rs**: plugin shortcut pathでNYASH_DISABLE_PLUGINS尊重
4. **tools/hako_check/render/graphviz.hako**: smart quotes修正(parse error解消)

## 根本原因
- NYASH_USE_PLUGIN_BUILTINS=1が自動設定され、ArrayBox/MapBoxがplugin経由で生成を試行
- bid/registry.rsで"Plugin loading temporarily disabled"の状態でも試行されエラー
- mod.rs:272のshortcut pathがNYASH_DISABLE_PLUGINSを無視していた

## テスト結果
- 10/11 PASS(HC011,13-18,21-22,31)
- HC012: 既存issue(JSON安定化未完)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-08 15:49:25 +09:00
parent cef820596f
commit 772149c86d
26 changed files with 508 additions and 62 deletions

View File

@ -166,9 +166,23 @@ impl MirInterpreter {
let ret = if func.signature.params.len() == 0 {
self.execute_function(func)?
} else {
// Build argv from NYASH_SCRIPT_ARGS_JSON (set by CLI when using `--`) or NYASH_ARGV (JSON array)
// Build argv from (priority) HEX JSON, normal JSON, or NYASH_ARGV
// 1) NYASH_SCRIPT_ARGS_HEX_JSON: JSON array of hex-encoded UTF-8 strings
// 2) NYASH_SCRIPT_ARGS_JSON: JSON array of strings
// 3) NYASH_ARGV: JSON array (legacy)
let mut argv_list: Vec<String> = Vec::new();
if let Ok(s) = std::env::var("NYASH_SCRIPT_ARGS_JSON") {
if let Ok(s) = std::env::var("NYASH_SCRIPT_ARGS_HEX_JSON") {
if let Ok(v) = serde_json::from_str::<Vec<String>>(&s) {
let mut out = Vec::with_capacity(v.len());
for hx in v.into_iter() {
match hex_decode_to_string(&hx) {
Ok(ss) => out.push(ss),
Err(_) => out.push(String::new()),
}
}
argv_list = out;
}
} else if let Ok(s) = std::env::var("NYASH_SCRIPT_ARGS_JSON") {
if let Ok(v) = serde_json::from_str::<Vec<String>>(&s) { argv_list = v; }
} else if let Ok(s) = std::env::var("NYASH_ARGV") {
if let Ok(v) = serde_json::from_str::<Vec<String>>(&s) { argv_list = v; }
@ -196,3 +210,26 @@ impl MirInterpreter {
self.exec_function_inner(func, None)
}
}
fn hex_decode_to_string(hex: &str) -> Result<String, ()> {
let mut bytes: Vec<u8> = Vec::with_capacity(hex.len() / 2);
let mut it = hex.as_bytes().iter().cloned();
while let (Some(h), Some(l)) = (it.next(), it.next()) {
let hi = from_hex(h).ok_or(())?;
let lo = from_hex(l).ok_or(())?;
bytes.push((hi << 4) | lo);
}
match String::from_utf8(bytes) {
Ok(s) => Ok(s),
Err(e) => Ok(String::from_utf8_lossy(e.as_bytes()).into_owned()),
}
}
fn from_hex(b: u8) -> Option<u8> {
match b {
b'0'..=b'9' => Some(b - b'0'),
b'a'..=b'f' => Some(b - b'a' + 10),
b'A'..=b'F' => Some(b - b'A' + 10),
_ => None,
}
}