fix(tvix/eval): Return error rather than panicking on bad substring

If builtins.substring is invoked with (byte!!) offsets that aren't at
codepoint boundaries, return an error rather than panicking. This is
still incorrect (see b/337) but pushes the incorrectness forward a step.

Change-Id: I5a4261f2ff250874cd36489ef598dcf886669d04
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10199
Tested-by: BuildkiteCI
Autosubmit: grfn <grfn@gws.fyi>
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Aspen Smith 2023-12-05 17:11:45 -05:00 committed by clbot
parent 41235bf908
commit 8135a8d38c
2 changed files with 10 additions and 1 deletions

View file

@ -951,7 +951,7 @@ mod pure_builtins {
cmp::min(beg + (len as usize), x.as_str().len()) cmp::min(beg + (len as usize), x.as_str().len())
}; };
Ok(Value::String(x.as_str()[beg..end].into())) Ok(Value::String(x.as_bytes()[beg..end].try_into()?))
} }
#[builtin("tail")] #[builtin("tail")]

View file

@ -8,6 +8,7 @@ use std::ffi::OsStr;
use std::hash::Hash; use std::hash::Hash;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::str::{self, Utf8Error};
use std::{borrow::Cow, fmt::Display, str::Chars}; use std::{borrow::Cow, fmt::Display, str::Chars};
use serde::de::{Deserializer, Visitor}; use serde::de::{Deserializer, Visitor};
@ -37,6 +38,14 @@ impl Ord for NixString {
} }
} }
impl TryFrom<&[u8]> for NixString {
type Error = Utf8Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(Box::from(str::from_utf8(value)?)))
}
}
impl From<&str> for NixString { impl From<&str> for NixString {
fn from(s: &str) -> Self { fn from(s: &str) -> Self {
NixString(Box::from(s)) NixString(Box::from(s))