Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ pub(crate) fn evaluate_index(
}
Ok(Value::String(chars[true_idx as usize].to_string()))
}
Value::Bytes(b) => {
let idx_int = match idx_val {
Value::Int(i) => i,
_ => {
return interp.error(
EldritchErrorKind::TypeError,
"bytes indices must be integers",
index.span,
);
}
};
let len = b.len() as i64;
let true_idx = if idx_int < 0 { len + idx_int } else { idx_int };
if true_idx < 0 || true_idx as usize >= b.len() {
return interp.error(
EldritchErrorKind::IndexError,
"Bytes index out of range",
span,
);
}
Ok(Value::Int(b[true_idx as usize] as i64))
}
_ => interp.error(
EldritchErrorKind::TypeError,
&format!("'{}' object is not subscriptable", get_type_name(&obj_val)),
Expand Down Expand Up @@ -249,6 +271,28 @@ pub(crate) fn evaluate_slice(
}
Ok(Value::String(result_chars.into_iter().collect()))
}
Value::Bytes(b) => {
let len = b.len() as i64;
let (i, j) = adjust_slice_indices(len, &start_val_opt, &stop_val_opt, step_val);
let mut result_bytes = Vec::new();
let mut curr = i;
if step_val > 0 {
while curr < j {
if curr >= 0 && curr < len {
result_bytes.push(b[curr as usize]);
}
curr += step_val;
}
} else {
while curr > j {
if curr >= 0 && curr < len {
result_bytes.push(b[curr as usize]);
}
curr += step_val;
}
}
Ok(Value::Bytes(result_bytes))
}
_ => interp.error(
EldritchErrorKind::TypeError,
&format!("'{}' object is not subscriptable", get_type_name(&obj_val)),
Expand Down
36 changes: 36 additions & 0 deletions implants/lib/eldritchv2/eldritch-core/tests/bytes_subscript.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use eldritch_core::{Interpreter, Value};

#[test]
fn test_bytes_subscript() {
let mut interp = Interpreter::new();
let code = r#"
b = b"hello world"
a = b[0]
b_slice = b[0:5]
b_slice_step = b[::2]
"#;

interp.interpret(code).unwrap();

// Check results by interpreting expressions that return the values
let a = interp.interpret("a").unwrap();
if let Value::Int(i) = a {
assert_eq!(i, 104); // 'h'
} else {
panic!("b[0] should be Int, got {:?}", a);
}

let b_slice = interp.interpret("b_slice").unwrap();
if let Value::Bytes(b) = b_slice {
assert_eq!(b, b"hello".to_vec());
} else {
panic!("b[0:5] should be Bytes, got {:?}", b_slice);
}

let b_slice_step = interp.interpret("b_slice_step").unwrap();
if let Value::Bytes(b) = b_slice_step {
assert_eq!(b, b"hlowrd".to_vec());
} else {
panic!("b[::2] should be Bytes, got {:?}", b_slice_step);
}
}
Loading