Fix panics on invalid indexes

This commit is contained in:
Alex Bethel 2021-08-16 15:06:40 -06:00
parent 92134d68d5
commit 4c3d44dfd8

View file

@ -1,6 +1,6 @@
use std::{ use std::{
cell::RefCell, collections::HashMap, fmt::Display, hash::Hash, io::Write, mem::discriminant, cell::RefCell, collections::HashMap, convert::TryFrom, fmt::Display, hash::Hash, io::Write,
rc::Rc, mem::discriminant, rc::Rc,
}; };
use rand::Rng; use rand::Rng;
@ -138,15 +138,26 @@ impl Value {
pub fn index(&self, index: &Value) -> Rc<RefCell<Value>> { pub fn index(&self, index: &Value) -> Rc<RefCell<Value>> {
Rc::new(RefCell::new(match self { Rc::new(RefCell::new(match self {
Value::Nul => Value::Nul, Value::Nul => Value::Nul,
Value::Str(s) => Value::Int(s.as_bytes()[index.to_i32() as usize] as i32), Value::Str(s) => Value::Int(
Value::Int(i) => { usize::try_from(index.to_i32() - 1)
Value::Int((format!("{}", i).as_bytes()[index.to_i32() as usize] - b'0') as i32) .ok()
} .and_then(|idx| s.as_bytes().get(idx).cloned())
.map(|value| value as i32)
.unwrap_or(0),
),
Value::Int(i) => Value::Int(
usize::try_from(index.to_i32() - 1)
.ok()
.and_then(|idx| format!("{}", i).as_bytes().get(idx).cloned())
.map(|value| value as i32)
.unwrap_or(0),
),
Value::Bool(b) => Value::Int( Value::Bool(b) => Value::Int(
format!("{}", b) usize::try_from(index.to_i32() - 1)
.chars() .ok()
.nth(index.to_i32() as usize) .and_then(|idx| format!("{}", b).as_bytes().get(idx).cloned())
.unwrap_or('?') as i32, .map(|value| value as i32)
.unwrap_or(0),
), ),
Value::Abool(b) => Value::Int(*b as i32), Value::Abool(b) => Value::Int(*b as i32),
Value::Functio(_) => Value::Int(42), Value::Functio(_) => Value::Int(42),