diff --git a/docs/_docs/user-guide/eldritchv2.md b/docs/_docs/user-guide/eldritchv2.md index d6fe98c3e..7f97dc488 100644 --- a/docs/_docs/user-guide/eldritchv2.md +++ b/docs/_docs/user-guide/eldritchv2.md @@ -1965,7 +1965,6 @@ It supports: - `args` (`List`): List of arguments. - `disown` (`Option`): If `True`, runs in background/detached. - `env_vars` (`Option>`): Environment variables to set. - - `input` (`Option`): String to pass to process stdin **Returns** - `Dict`: Output containing `stdout`, `stderr`, and `status` (exit code). diff --git a/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs b/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs index 07fc7f640..7f995befc 100644 --- a/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs +++ b/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs @@ -279,6 +279,33 @@ fn evaluate_index( ), } } + Value::String(s) => { + let idx_int = match idx_val { + Value::Int(i) => i, + _ => { + return interp.error( + EldritchErrorKind::TypeError, + "string indices must be integers", + index.span, + ); + } + }; + let chars: Vec = s.chars().collect(); + let len = chars.len() as i64; + let true_idx = if idx_int < 0 { + len + idx_int + } else { + idx_int + }; + if true_idx < 0 || true_idx as usize >= chars.len() { + return interp.error( + EldritchErrorKind::IndexError, + "String index out of range", + span, + ); + } + Ok(Value::String(chars[true_idx as usize].to_string())) + } _ => interp.error( EldritchErrorKind::TypeError, &format!("'{}' object is not subscriptable", get_type_name(&obj_val)), diff --git a/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs b/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs index 8a5521830..9b4547ea7 100644 --- a/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs +++ b/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs @@ -78,18 +78,7 @@ pub fn get_dir_attributes(value: &Value) -> Vec { "union".to_string(), "update".to_string(), ], - Value::String(_) => vec![ - "endswith".to_string(), - "find".to_string(), - "format".to_string(), - "join".to_string(), - "lower".to_string(), - "replace".to_string(), - "split".to_string(), - "startswith".to_string(), - "strip".to_string(), - "upper".to_string(), - ], + Value::String(s) => super::methods::get_native_methods(&Value::String(s.clone())), Value::Foreign(f) => f.method_names(), _ => Vec::new(), }; diff --git a/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs b/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs index 308231483..21a21f340 100644 --- a/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs +++ b/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs @@ -25,10 +25,7 @@ fn test_eval_index_out_of_bounds() { assert::fail("(1,)[-2]", "Tuple index out of range"); // String - // Eldritch doesn't seem to support string indexing in eval.rs yet? - // Wait, evaluate_index only handles List, Tuple, Dictionary. - // Let's verify this failure. - assert::fail("'abc'[0]", "'string' object is not subscriptable"); + assert::fail("'abc'[10]", "String index out of range"); } #[test]