From 938f588769478fab851f9d84179a98cf1c4750b6 Mon Sep 17 00:00:00 2001 From: Skgland Date: Sat, 25 Apr 2026 21:17:48 +0200 Subject: [PATCH 1/5] make crypto depending on ring optional --- Cargo.toml | 19 +- src/machine/system_calls.rs | 588 +++++++++++++++++++++--------------- 2 files changed, 362 insertions(+), 245 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 72fd5559..4cfbda93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,16 +17,25 @@ rust-version = "1.93.1" crate-type = ["cdylib", "rlib"] [features] -default = ["ffi", "repl", "hostname", "tls", "http", "crypto-full"] +default = ["all-simple-cross", "tls", "http"] +# activates all features that depend on no non pure-rust dependencies +# +# currently does not include +# ffi due to libffi +# tls, http due to openssl +# crypto-inpure due to ring +all-pure = ["repl", "hostname"] # enables all features that are simple to get working for cross-compliation # currently all but tls, http as those depend on openssl -all-simple-cross = ["ffi", "repl", "hostname", "crypto-full"] +all-simple-cross = ["all-pure", "ffi", "crypto-full"] ffi = ["dep:libffi"] repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"] hostname = ["dep:hostname"] tls = ["dep:native-tls"] http = ["dep:warp", "dep:reqwest"] -crypto-full = [] +# crypto function that require non pure-rust dependencies +crypto-inpure = ["dep:ring"] +crypto-full = ["crypto-inpure"] [lints.rust] unexpected_cfgs = { level = "deny", check-cfg = [ @@ -73,7 +82,9 @@ ordered-float = "5.0.0" phf = { version = "0.11", features = ["macros"] } puruspe = "0.4.1" rand = "0.8.5" -ring = { version = "0.17.8", features = ["wasm32_unknown_unknown_js"] } +ring = { version = "0.17.8", features = [ + "wasm32_unknown_unknown_js", +], optional = true } ripemd = "0.1.3" roxmltree = "0.20.0" ryu = "1.0.18" diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index d80a9565..692b558e 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -53,7 +53,6 @@ use std::mem; #[cfg(feature = "http")] use std::net::{SocketAddr, ToSocketAddrs}; use std::net::{TcpListener, TcpStream}; -use std::num::NonZeroU32; use std::process; use std::process::Child; use std::process::Stdio; @@ -74,11 +73,15 @@ use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifier use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use blake2::{Blake2b512, Blake2s256}; -use ring::rand::{SecureRandom, SystemRandom}; -use ring::{digest, hkdf, hmac, pbkdf2}; #[cfg(feature = "crypto-full")] use ring::aead; +#[cfg(feature = "crypto-inpure")] +use ring::{ + digest, hkdf, hmac, pbkdf2, + rand::{SecureRandom, SystemRandom}, +}; + use ripemd::{Digest, Ripemd160}; use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512}; @@ -96,8 +99,6 @@ use roxmltree; use futures::future; #[cfg(feature = "http")] use reqwest::Url; -use tokio::runtime::Handle; -use tokio::task; #[cfg(feature = "http")] use warp::hyper::header::{HeaderName, HeaderValue}; #[cfg(feature = "http")] @@ -4403,6 +4404,8 @@ impl Machine { #[cfg(feature = "http")] #[inline(always)] pub(crate) fn http_open(&mut self) -> CallResult { + use tokio::task; + let address_sink = self.deref_register(1); let method = read_heap_cell!(self.deref_register(3), (HeapCellValueTag::Atom, (name, arity)) => { @@ -4466,7 +4469,7 @@ impl Machine { // do it! task::block_in_place(move || { - match Handle::current().block_on(req.send()) { + match tokio::runtime::Handle::current().block_on(req.send()) { Ok(resp) => { // status code let status = resp.status().as_u16(); @@ -7843,22 +7846,33 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_random_byte(&mut self) { - let arg = self.machine_st.registers[1]; - let mut bytes: [u8; 1] = [0]; + #[cfg(feature = "crypto-inpure")] + { + let arg = self.machine_st.registers[1]; + let mut bytes: [u8; 1] = [0]; - match rng().fill(&mut bytes) { - Ok(()) => {} - Err(_) => { - // the error payload here is of type 'Unspecified', - // which contains no information whatsoever. So, for now, - // just fail. - self.machine_st.fail = true; - return; + match rng().fill(&mut bytes) { + Ok(()) => {} + Err(_) => { + // the error payload here is of type 'Unspecified', + // which contains no information whatsoever. So, for now, + // just fail. + self.machine_st.fail = true; + return; + } } + + let byte = Fixnum::build_with(bytes[0]); + self.machine_st.unify_fixnum(byte, arg); } - let byte = Fixnum::build_with(bytes[0]); - self.machine_st.unify_fixnum(byte, arg); + #[cfg(not(feature = "crypto-inpure"))] + { + let stub_gen = || functor_stub(atom!("crypto_random_byte"), 1); + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] @@ -7990,29 +8004,40 @@ impl Machine { ) } _ => { - let ints = digest::digest( - match algorithm { - atom!("sha256") => &digest::SHA256, - atom!("sha384") => &digest::SHA384, - atom!("sha512") => &digest::SHA512, - atom!("sha512_256") => &digest::SHA512_256, - _ => { - unreachable!() - } - }, - &bytes, - ); + #[cfg(feature = "crypto-inpure")] + { + let ints = digest::digest( + match algorithm { + atom!("sha256") => &digest::SHA256, + atom!("sha384") => &digest::SHA384, + atom!("sha512") => &digest::SHA512, + atom!("sha512_256") => &digest::SHA512_256, + _ => { + unreachable!() + } + }, + &bytes, + ); - step_or_resource_error!( - self.machine_st, - sized_iter_to_heap_list( - &mut self.machine_st.heap, - ints.as_ref().len(), - ints.as_ref() - .iter() - .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + step_or_resource_error!( + self.machine_st, + sized_iter_to_heap_list( + &mut self.machine_st.heap, + ints.as_ref().len(), + ints.as_ref() + .iter() + .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + ) ) - ) + } + #[cfg(not(feature = "crypto-inpure"))] + { + let stub_gen = || functor_stub(atom!("crypto_data_hash"), 1); + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + return; + } } }; @@ -8021,168 +8046,201 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_hmac(&mut self) { - let encoding = cell_as_atom!(self.deref_register(2)); - let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); - let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3); - let key = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[3], stub_gen); + #[cfg(feature = "crypto-inpure")] + { + let encoding = cell_as_atom!(self.deref_register(2)); + let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); - let algorithm = cell_as_atom!(self.deref_register(5)); - let ralg = match algorithm { - atom!("sha256") => hmac::HMAC_SHA256, - atom!("sha384") => hmac::HMAC_SHA384, - atom!("sha512") => hmac::HMAC_SHA512, - _ => { - unreachable!() - } - }; + let key = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[3], stub_gen); - let rkey = hmac::Key::new(ralg, key.as_ref()); - let tag = hmac::sign(&rkey, &data); + let algorithm = cell_as_atom!(self.deref_register(5)); + let ralg = match algorithm { + atom!("sha256") => hmac::HMAC_SHA256, + atom!("sha384") => hmac::HMAC_SHA384, + atom!("sha512") => hmac::HMAC_SHA512, + _ => { + unreachable!() + } + }; - let ints_list = step_or_resource_error!( - self.machine_st, - sized_iter_to_heap_list( - &mut self.machine_st.heap, - tag.as_ref().len(), - tag.as_ref() - .iter() - .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) - ) - ); + let rkey = hmac::Key::new(ralg, key.as_ref()); + let tag = hmac::sign(&rkey, &data); - unify!(self.machine_st, self.machine_st.registers[4], ints_list); + let ints_list = step_or_resource_error!( + self.machine_st, + sized_iter_to_heap_list( + &mut self.machine_st.heap, + tag.as_ref().len(), + tag.as_ref() + .iter() + .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + ) + ); + + unify!(self.machine_st, self.machine_st.registers[4], ints_list); + } + + #[cfg(not(feature = "crypto-inpure"))] + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] pub(crate) fn crypto_data_hkdf(&mut self) { - let encoding = cell_as_atom!(self.deref_register(2)); - let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); - let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); - let salt = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[3], stub1_gen); - let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); - let info = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[4], stub2_gen); + #[cfg(feature = "crypto-inpure")] + { + let encoding = cell_as_atom!(self.deref_register(2)); + let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); - let algorithm = cell_as_atom!(self.deref_register(5)); + let salt = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[3], stub1_gen); - let length = self.deref_register(6); + let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); + let info = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[4], stub2_gen); - let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) { - Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(), - Ok(Number::Integer(n)) => match (&*n).try_into() as Result { - Ok(u) => u, + let algorithm = cell_as_atom!(self.deref_register(5)); + + let length = self.deref_register(6); + + let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) { + Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(), + Ok(Number::Integer(n)) => match (&*n).try_into() as Result { + Ok(u) => u, + _ => { + self.machine_st.fail = true; + return; + } + }, _ => { - self.machine_st.fail = true; - return; - } - }, - _ => { - unreachable!() - } - }; - - let ints_list = { - let digest_alg = match algorithm { - atom!("sha256") => hkdf::HKDF_SHA256, - atom!("sha384") => hkdf::HKDF_SHA384, - atom!("sha512") => hkdf::HKDF_SHA512, - _ => { - self.machine_st.fail = true; - return; + unreachable!() } }; - let salt = hkdf::Salt::new(digest_alg, &salt); - let mut bytes: Vec = vec![0; length]; + let ints_list = { + let digest_alg = match algorithm { + atom!("sha256") => hkdf::HKDF_SHA256, + atom!("sha384") => hkdf::HKDF_SHA384, + atom!("sha512") => hkdf::HKDF_SHA512, + _ => { + self.machine_st.fail = true; + return; + } + }; - match salt.extract(&data).expand(&[&info[..]], MyKey(length)) { - Ok(r) => { - r.fill(&mut bytes).unwrap(); - } - _ => { - self.machine_st.fail = true; - return; - } - } + let salt = hkdf::Salt::new(digest_alg, &salt); + let mut bytes: Vec = vec![0; length]; - step_or_resource_error!( - self.machine_st, - sized_iter_to_heap_list( - &mut self.machine_st.heap, - bytes.len(), - bytes - .iter() - .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) - ) - ) - }; - - unify!(self.machine_st, self.machine_st.registers[7], ints_list); - } - - #[inline(always)] - pub(crate) fn crypto_password_hash(&mut self) { - let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3); - let data = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[1], stub1_gen); - let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3); - let salt = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[2], stub2_gen); - - let iterations = self.deref_register(3); - - let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) { - Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(), - Ok(Number::Integer(n)) => { - let n: Result = (&*n).try_into(); - match n { - Ok(i) => i, + match salt.extract(&data).expand(&[&info[..]], MyKey(length)) { + Ok(r) => { + r.fill(&mut bytes).unwrap(); + } _ => { self.machine_st.fail = true; return; } } - } - _ => { - unreachable!() - } - }; - let ints_list = { - let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN]; - - pbkdf2::derive( - pbkdf2::PBKDF2_HMAC_SHA512, - NonZeroU32::new(iterations as u32).unwrap(), - &salt, - &data, - &mut bytes, - ); - - step_or_resource_error!( - self.machine_st, - sized_iter_to_heap_list( - &mut self.machine_st.heap, - bytes.len(), - bytes - .iter() - .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + step_or_resource_error!( + self.machine_st, + sized_iter_to_heap_list( + &mut self.machine_st.heap, + bytes.len(), + bytes + .iter() + .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + ) ) - ) - }; + }; - unify!(self.machine_st, self.machine_st.registers[4], ints_list); + unify!(self.machine_st, self.machine_st.registers[7], ints_list); + } + + #[cfg(not(feature = "crypto-inpure"))] + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub1_gen()); + self.machine_st.throw_exception(exception); + } + } + + #[inline(always)] + pub(crate) fn crypto_password_hash(&mut self) { + let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3); + + #[cfg(feature = "crypto-inpure")] + { + use std::num::NonZeroU32; + let data = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[1], stub1_gen); + let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3); + let salt = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[2], stub2_gen); + + let iterations = self.deref_register(3); + + let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) { + Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(), + Ok(Number::Integer(n)) => { + let n: Result = (&*n).try_into(); + match n { + Ok(i) => i, + _ => { + self.machine_st.fail = true; + return; + } + } + } + _ => { + unreachable!() + } + }; + + let ints_list = { + let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN]; + + pbkdf2::derive( + pbkdf2::PBKDF2_HMAC_SHA512, + NonZeroU32::new(iterations as u32).unwrap(), + &salt, + &data, + &mut bytes, + ); + + step_or_resource_error!( + self.machine_st, + sized_iter_to_heap_list( + &mut self.machine_st.heap, + bytes.len(), + bytes + .iter() + .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + ) + ) + }; + + unify!(self.machine_st, self.machine_st.registers[4], ints_list); + } + + #[cfg(not(feature = "crypto-inpure"))] + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub1_gen()); + self.machine_st.throw_exception(exception); + } } #[cfg(feature = "crypto-full")] @@ -8304,109 +8362,153 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_curve_scalar_mult(&mut self) { let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 4); - let scalar_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[2], stub_gen); - let point_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[3], stub_gen); - let mut point = secp256k1::Point::decode(&point_bytes).unwrap(); - let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes); - point *= scalar; + { + let scalar_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[2], stub_gen); + let point_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[3], stub_gen); - let uncompressed = step_or_resource_error!( - self.machine_st, - self.u8s_to_string(&point.encode_uncompressed()) - ); + let mut point = secp256k1::Point::decode(&point_bytes).unwrap(); + let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes); + point *= scalar; - unify!(self.machine_st, self.machine_st.registers[4], uncompressed); + let uncompressed = step_or_resource_error!( + self.machine_st, + self.u8s_to_string(&point.encode_uncompressed()) + ); + + unify!(self.machine_st, self.machine_st.registers[4], uncompressed); + } + + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] pub(crate) fn ed25519_seed_to_public_key(&mut self) { let stub_gen = || functor_stub(atom!("ed25519_seed_keypair"), 2); - let seed_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[1], stub_gen); - let skey = ed25519::PrivateKey::from_seed(&seed_bytes); + { + let seed_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[1], stub_gen); - let complete_string = step_or_resource_error!( - self.machine_st, - self.u8s_to_string(skey.public_key.encoded.as_ref()) - ); + let skey = ed25519::PrivateKey::from_seed(&seed_bytes); - unify!( - self.machine_st, - self.machine_st.registers[2], - complete_string - ); + let complete_string = step_or_resource_error!( + self.machine_st, + self.u8s_to_string(skey.public_key.encoded.as_ref()) + ); + + unify!( + self.machine_st, + self.machine_st.registers[2], + complete_string + ); + } + + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] pub(crate) fn ed25519_sign_raw(&mut self) { let stub_gen = || functor_stub(atom!("ed25519_sign"), 4); - let seed_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[1], stub_gen); - let skey = ed25519::PrivateKey::from_seed(&seed_bytes); + { + let seed_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[1], stub_gen); - let encoding = cell_as_atom!(self.deref_register(3)); - let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding); + let skey = ed25519::PrivateKey::from_seed(&seed_bytes); - let sig = skey.sign_raw(&data); - let sig_list = step_or_resource_error!( - self.machine_st, - sized_iter_to_heap_list( - &mut self.machine_st.heap, - sig.as_ref().len(), - sig.as_ref() - .iter() - .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) - ) - ); + let encoding = cell_as_atom!(self.deref_register(3)); + let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding); - unify!(self.machine_st, self.machine_st.registers[4], sig_list); + let sig = skey.sign_raw(&data); + let sig_list = step_or_resource_error!( + self.machine_st, + sized_iter_to_heap_list( + &mut self.machine_st.heap, + sig.as_ref().len(), + sig.as_ref() + .iter() + .map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) + ) + ); + + unify!(self.machine_st, self.machine_st.registers[4], sig_list); + } + + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] pub(crate) fn ed25519_verify_raw(&mut self) { - let key_bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet")); - let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap(); - - let encoding = cell_as_atom!(self.deref_register(3)); - let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding); - let stub_gen = || functor_stub(atom!("ed25519_verify"), 4); - let signature = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[4], stub_gen); + { + let key_bytes = + self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet")); + let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap(); - self.machine_st.fail = !pkey.verify_raw(&signature, &data); + let encoding = cell_as_atom!(self.deref_register(3)); + let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding); + + let signature = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[4], stub_gen); + + self.machine_st.fail = !pkey.verify_raw(&signature, &data); + } + + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] pub(crate) fn curve25519_scalar_mult(&mut self) { - let stub1_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3); - let scalar_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[1], stub1_gen); - let stub2_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3); - let point_bytes = self - .machine_st - .integers_to_bytevec(self.machine_st.registers[2], stub2_gen); + let stub_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3); - let result = x25519::x25519( - &<[u8; 32]>::try_from(&point_bytes[..]).unwrap(), - &<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(), - ); + { + let scalar_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[1], stub_gen); + let point_bytes = self + .machine_st + .integers_to_bytevec(self.machine_st.registers[2], stub_gen); - let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..])); + let result = x25519::x25519( + &<[u8; 32]>::try_from(&point_bytes[..]).unwrap(), + &<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(), + ); - unify!(self.machine_st, self.machine_st.registers[3], string); + let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..])); + + unify!(self.machine_st, self.machine_st.registers[3], string); + } + + { + let err = self.machine_st.missing_feature_error(atom!("crypto")); + let exception = self.machine_st.error_form(err, stub_gen()); + self.machine_st.throw_exception(exception); + } } #[inline(always)] @@ -9509,7 +9611,9 @@ impl Machine { } } +#[cfg(feature = "crypto-inpure")] fn rng() -> &'static dyn SecureRandom { + use lazy_static::lazy_static; use std::ops::Deref; static RANDOM: LazyLock = LazyLock::new(SystemRandom::new); @@ -9517,8 +9621,10 @@ fn rng() -> &'static dyn SecureRandom { RANDOM.deref() } +#[cfg(feature = "crypto-inpure")] struct MyKey(T); +#[cfg(feature = "crypto-inpure")] impl hkdf::KeyType for MyKey { fn len(&self) -> usize { self.0 From 6150ca90d313635e3e066b6e363ca86b8cff8178 Mon Sep 17 00:00:00 2001 From: Skgland Date: Mon, 27 Apr 2026 22:53:05 +0200 Subject: [PATCH 2/5] check individual features in CI --- .github/workflows/check_features.sh | 12 ++++++++++++ .github/workflows/ci.yml | 11 ++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100755 .github/workflows/check_features.sh diff --git a/.github/workflows/check_features.sh b/.github/workflows/check_features.sh new file mode 100755 index 00000000..8dbb1537 --- /dev/null +++ b/.github/workflows/check_features.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e + +echo "Checking all feature at once" +cargo check -q --all-targets --all-features "$@" + +features=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name = "scryer-prolog") | .features | keys | join(" ")') + +for feature in ${features} ; do + echo "Checking feature ${feature} in isolation" + cargo check -q --all-targets --no-default-features --features=${feature} "$@" +done diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff0993a2..9fbb2f1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,10 +53,10 @@ jobs: matrix: include: # operating systems - - { os: windows-latest, rust-version: stable, target: 'x86_64-pc-windows-msvc', publish: true } - - { os: macos-latest, rust-version: stable, target: 'x86_64-apple-darwin', publish: true } + - { os: windows-latest, rust-version: stable, target: 'x86_64-pc-windows-msvc', publish: true, check-features: true } + - { os: macos-latest, rust-version: stable, target: 'x86_64-apple-darwin', publish: true, check-features: true } # architectures - - { os: ubuntu-22.04, rust-version: stable, target: 'x86_64-unknown-linux-gnu', publish: true } + - { os: ubuntu-22.04, rust-version: stable, target: 'x86_64-unknown-linux-gnu', publish: true, check-features: true } - { os: ubuntu-22.04, rust-version: stable, target: 'i686-unknown-linux-gnu', publish: true } # FIXME(issue #2138): run wasm tests, failing to run since https://github.com/mthom/scryer-prolog/pull/2137 removed wasm-pack - { os: ubuntu-22.04, rust-version: nightly, target: 'wasm32-unknown-unknown', publish: true, args: '--no-default-features' , test-args: '--no-run --no-default-features', use_swap: true } @@ -88,9 +88,14 @@ jobs: # Build and test. - name: Build library run: cargo build --all-targets --target ${{ matrix.target }} ${{ matrix.args }} --verbose + - name: Test run: cargo test --target ${{ matrix.target }} ${{ matrix.test-args }} --all + - name: Check features + if: matrix.check-features + run: bash ./.github/workflows/check_features.sh --target ${{ matrix.target }} + - name: Check miri if: matrix.miri run: cargo miri test --target ${{ matrix.target }} ${{ matrix.args }} From f2195c2362e5abb3ab29b2ae0df189c0ee77f7c1 Mon Sep 17 00:00:00 2001 From: Skgland Date: Mon, 27 Apr 2026 22:54:36 +0200 Subject: [PATCH 3/5] cleanup - fix some warnings and mark others as expected - make use of the msrv bump to 1.93.1 and cleanup compat and workarounds --- .github/actions/setup-rust/cleanup.sh | 2 +- Cargo.toml | 4 +- src/arena.rs | 4 +- src/codegen.rs | 6 +-- src/lib.rs | 2 + src/machine/copier.rs | 11 ++-- src/machine/disjuncts.rs | 4 +- src/machine/heap.rs | 2 +- src/machine/machine_errors.rs | 3 ++ src/machine/machine_state.rs | 8 ++- src/machine/stack.rs | 6 +-- src/machine/streams.rs | 5 +- src/machine/streams/compat.rs | 72 --------------------------- src/machine/system_calls.rs | 44 +++++++--------- tests/scryer/issues.rs | 5 +- 15 files changed, 49 insertions(+), 129 deletions(-) delete mode 100644 src/machine/streams/compat.rs diff --git a/.github/actions/setup-rust/cleanup.sh b/.github/actions/setup-rust/cleanup.sh index 280f5e98..d3411202 100755 --- a/.github/actions/setup-rust/cleanup.sh +++ b/.github/actions/setup-rust/cleanup.sh @@ -4,7 +4,7 @@ set -e echo Cleanup workspace build artifacts and extra target output # clean just the direct members of the current workspace, use cargo metadata to generalize to all rust projects -cargo clean -p `cargo metadata --no-deps --offline --format-version 1 | jq -r '[.workspace_members[]|split(" ")|.[0]]|join(" ")'` +cargo clean --workspace # remove directories in /target/ that are not named `debug` or `release` before=`du -s target | awk '{print $1}'` diff --git a/Cargo.toml b/Cargo.toml index 4cfbda93..5154456c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,13 +37,15 @@ http = ["dep:warp", "dep:reqwest"] crypto-inpure = ["dep:ring"] crypto-full = ["crypto-inpure"] +[lints.clippy] +collapsible_match = "allow" + [lints.rust] unexpected_cfgs = { level = "deny", check-cfg = [ 'cfg(rust_version, values("1.87.0"))', ] } function_casts_as_integer = "deny" - [build-dependencies] proc-macro2 = "1.0.86" quote = "1.0.36" diff --git a/src/arena.rs b/src/arena.rs index ffb92fb7..01c2d697 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -13,6 +13,8 @@ use ordered_float::OrderedFloat; use std::fmt; use std::fmt::Debug; use std::hash::{Hash, Hasher}; +use std::io::PipeReader; +use std::io::PipeWriter; use std::mem; use std::mem::ManuallyDrop; use std::net::TcpListener; @@ -22,8 +24,6 @@ use std::ptr; use std::ptr::addr_of_mut; use std::ptr::NonNull; -use crate::machine::streams::{PipeReader, PipeWriter}; - macro_rules! arena_alloc { ($e:expr, $arena:expr) => {{ let result = $e; diff --git a/src/codegen.rs b/src/codegen.rs index 19d056d6..b19dc8ae 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -145,7 +145,7 @@ impl BranchCodeStack { settings.trust_me() }); - combined_code.extend(code.into_iter()); + combined_code.extend(code); } } @@ -1236,7 +1236,7 @@ impl CodeGenerator { } self.skeleton.clauses.push_back(clause_index_info); - code.extend(clause_code.into_iter()); + code.extend(clause_code); } let index_code = if clauses_len > 1 || self.settings.is_extensible { @@ -1313,7 +1313,7 @@ impl CodeGenerator { } } - code.extend(code_segment.into_iter()); + code.extend(code_segment); } Ok(code) diff --git a/src/lib.rs b/src/lib.rs index 4ad5a83b..ee73d4f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,8 @@ pub mod wasm; /// The entry point for the Scryer Prolog CLI. pub fn run_binary() -> std::process::ExitCode { use crate::atom_table::Atom; + + #[cfg(feature = "repl")] use crate::machine::INTERRUPT; #[cfg(feature = "repl")] diff --git a/src/machine/copier.rs b/src/machine/copier.rs index b71db32b..43631bf4 100644 --- a/src/machine/copier.rs +++ b/src/machine/copier.rs @@ -247,11 +247,12 @@ impl CopyTermState { self.trail .push((TrailRef::pstr_loc(pstr_loc_idx), old_cell)); - let old_tail_idx = if (pstr_loc + offset + 1) % Heap::heap_cell_alignment() == 0 { - cell_index!(pstr_loc + offset) + 2 - } else { - cell_index!(pstr_loc + offset) + 1 - }; + let old_tail_idx = + if (pstr_loc + offset + 1).is_multiple_of(Heap::heap_cell_alignment()) { + cell_index!(pstr_loc + offset) + 2 + } else { + cell_index!(pstr_loc + offset) + 1 + }; let tail_cell = self.target[old_tail_idx]; diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs index 65698e36..4548a121 100644 --- a/src/machine/disjuncts.rs +++ b/src/machine/disjuncts.rs @@ -549,7 +549,7 @@ impl VariableClassifier { let first_branch_num = Arc::new(self.current_branch_num.split()); let branches: Vec<_> = std::iter::once(head) - .chain(unfold_by_str(tail, atom!(";")).into_iter()) + .chain(unfold_by_str(tail, atom!(";"))) .collect(); let mut branch_numbers = vec![first_branch_num]; @@ -571,7 +571,7 @@ impl VariableClassifier { self.current_branch_num.halve_delta(), ))); - let iter = branches.into_iter().zip(branch_numbers.into_iter()); + let iter = branches.into_iter().zip(branch_numbers); let final_disjunct_loc = state_stack.len(); for (term, branch_num) in iter.rev() { diff --git a/src/machine/heap.rs b/src/machine/heap.rs index 70ef0ba3..7902b9e2 100644 --- a/src/machine/heap.rs +++ b/src/machine/heap.rs @@ -577,7 +577,7 @@ impl Heap { // takes a heap index, returns a cell index #[inline] pub const fn pstr_tail_idx(pstr_zero_byte_loc: usize) -> usize { - if (pstr_zero_byte_loc + 1) % Heap::heap_cell_alignment() == 0 { + if (pstr_zero_byte_loc + 1).is_multiple_of(Heap::heap_cell_alignment()) { cell_index!(pstr_zero_byte_loc) + 2 } else { cell_index!(pstr_zero_byte_loc) + 1 diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 52a87dfe..ec1a280d 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -937,6 +937,7 @@ impl Permission { } #[derive(Debug, Clone, Copy)] +#[cfg_attr(not(feature = "ffi"), expect(dead_code))] pub(crate) enum DomainErrorType { IOMode, NotLessThanZero, @@ -987,6 +988,7 @@ impl DomainErrorType { // from 7.12.2 f) of 13211-1:1995 #[derive(Debug, Clone, Copy)] +#[cfg_attr(not(feature = "ffi"), expect(dead_code))] pub(crate) enum RepFlag { Character, CharacterCode, @@ -1178,6 +1180,7 @@ impl MachineState { } #[derive(Debug)] +#[cfg_attr(not(feature = "ffi"), expect(dead_code))] pub enum ExistenceError { Module(Atom), ModuleSource(ModuleSource), diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 3744da34..edcd95c0 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -548,8 +548,7 @@ impl MachineState { return true; } - // use strict_add once msrv is >= 1.91.0 - self.cwil.global_count = self.cwil.global_count.checked_add(1).unwrap(); + self.cwil.global_count = self.cwil.global_count.strict_add(1); if let Some(&(ref limit, block)) = self.cwil.limits.last() { if self.cwil.local_count == *limit { @@ -651,7 +650,7 @@ impl MachineState { mut var_list: Vec<(VarKey, HeapCellValue, usize)>, singleton_heap_list: HeapCellValue, ) -> CallResult { - var_list.sort_by(|(_, _, idx_1), (_, _, idx_2)| idx_1.cmp(idx_2)); + var_list.sort_by_key(|(_, _, idx_1)| *idx_1); let singleton_addr = self.registers[3]; unify_fn!(*self, singleton_heap_list, singleton_addr); @@ -1128,8 +1127,7 @@ impl CWIL { } pub(crate) fn add_limit(&mut self, mut limit: u128, block: usize) -> u128 { - // use strict_add once msrv is >= 1.91.0 - limit = limit.checked_add(self.local_count).unwrap(); + limit = limit.strict_add(self.local_count); match self.limits.last() { Some((ref inner_limit, _)) if *inner_limit <= limit => {} diff --git a/src/machine/stack.rs b/src/machine/stack.rs index ad9b4755..c4bed865 100644 --- a/src/machine/stack.rs +++ b/src/machine/stack.rs @@ -195,8 +195,7 @@ impl Stack { // exposed provenance, we need to expose the provenance here, even though we don't // actually use the value for anything. This is a reminder that `expose_provenance` // isn't just a cast from a pointer to an integer but has actual side effects. - // FIXME(msrv) remove the as_ptr() call once MSRV reaches 1.89.0 - cell_ptr.as_ptr().expose_provenance(); + cell_ptr.expose_provenance(); offset += mem::size_of::(); } @@ -228,8 +227,7 @@ impl Stack { // exposed provenance, we need to expose the provenance here, even though we don't // actually use the value for anything. This is a reminder that `expose_provenance` // isn't just a cast from a pointer to an integer but has actual side effects. - // FIXME(msrv) remove as_ptr() call once msrv reaches 1.89.0 - cell_ptr.as_ptr().expose_provenance(); + cell_ptr.expose_provenance(); offset += mem::size_of::(); } diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 9a2d56f4..a956a00c 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -23,6 +23,8 @@ use std::fmt::Debug; use std::fs::{File, OpenOptions}; use std::hash::Hash; use std::io; +use std::io::PipeReader; +use std::io::PipeWriter; use std::io::{Cursor, ErrorKind, Read, Seek, SeekFrom, Write}; use std::mem::ManuallyDrop; use std::net::{Shutdown, TcpStream}; @@ -38,9 +40,6 @@ use native_tls::TlsStream; #[cfg(feature = "http")] use warp::hyper; -mod compat; -pub use compat::*; - #[derive(Debug, Specifier, Clone, Copy, PartialEq, Eq, Hash)] #[bits = 1] pub enum StreamType { diff --git a/src/machine/streams/compat.rs b/src/machine/streams/compat.rs deleted file mode 100644 index 45e370fa..00000000 --- a/src/machine/streams/compat.rs +++ /dev/null @@ -1,72 +0,0 @@ -#[cfg(rust_version = "1.87.0")] -pub use ge_1_87_0::{PipeReader, PipeWriter}; - -#[cfg(not(rust_version = "1.87.0"))] -pub use lt_1_87_0::{PipeReader, PipeWriter}; - -#[cfg(not(rust_version = "1.87.0"))] -pub(crate) use lt_1_87_0::PipeReaderInner; - -#[cfg(not(rust_version = "1.87.0"))] -mod lt_1_87_0 { - use std::process::{ChildStderr, ChildStdout}; - - pub type PipeWriter = std::process::ChildStdin; - - #[derive(Debug)] - pub struct PipeReader(pub(crate) PipeReaderInner); - - #[derive(Debug)] - pub(crate) enum PipeReaderInner { - Stdout(ChildStdout), - Stderr(ChildStderr), - } - - impl std::io::Read for PipeReader { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - match &mut self.0 { - PipeReaderInner::Stdout(child_stdout) => child_stdout.read(buf), - PipeReaderInner::Stderr(child_stderr) => child_stderr.read(buf), - } - } - - fn read_vectored( - &mut self, - bufs: &mut [std::io::IoSliceMut<'_>], - ) -> std::io::Result { - match &mut self.0 { - PipeReaderInner::Stdout(child_stdout) => child_stdout.read_vectored(bufs), - PipeReaderInner::Stderr(child_stderr) => child_stderr.read_vectored(bufs), - } - } - - fn read_to_end(&mut self, buf: &mut Vec) -> std::io::Result { - match &mut self.0 { - PipeReaderInner::Stdout(child_stdout) => child_stdout.read_to_end(buf), - PipeReaderInner::Stderr(child_stderr) => child_stderr.read_to_end(buf), - } - } - - fn read_to_string(&mut self, buf: &mut String) -> std::io::Result { - match &mut self.0 { - PipeReaderInner::Stdout(child_stdout) => child_stdout.read_to_string(buf), - PipeReaderInner::Stderr(child_stderr) => child_stderr.read_to_string(buf), - } - } - - fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { - match &mut self.0 { - PipeReaderInner::Stdout(child_stdout) => child_stdout.read_exact(buf), - PipeReaderInner::Stderr(child_stderr) => child_stderr.read_exact(buf), - } - } - } -} - -#[cfg(rust_version = "1.87.0")] -mod ge_1_87_0 { - #![allow(clippy::incompatible_msrv)] - - pub type PipeReader = std::io::PipeReader; - pub type PipeWriter = std::io::PipeWriter; -} diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 692b558e..5daa2af8 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -8950,36 +8950,27 @@ impl Machine { Some(atom!("std")) => Stdio::inherit(), Some(atom!("null")) => Stdio::null(), Some(atom!("pipe")) => { - #[cfg(rust_version = "1.87.0")] - #[allow(clippy::incompatible_msrv)] - { - let (reader, writer) = match std::io::pipe() { - Ok(pipe_pair) => pipe_pair, - Err(_) => { - return Err(self.machine_st.open_permission_error( - atom!("anonymous_pipe"), - atom!("process_create"), - 3, - )); - } - }; + let (reader, writer) = match std::io::pipe() { + Ok(pipe_pair) => pipe_pair, + Err(_) => { + return Err(self.machine_st.open_permission_error( + atom!("anonymous_pipe"), + atom!("process_create"), + 3, + )); + } + }; - let stream = Stream::from_pipe_writer(writer, &mut self.machine_st.arena); + let stream = Stream::from_pipe_writer(writer, &mut self.machine_st.arena); - self.indices - .add_stream(stream, atom!("process_create"), 3) - .map_err(|stub_gen| stub_gen(&mut self.machine_st))?; + self.indices + .add_stream(stream, atom!("process_create"), 3) + .map_err(|stub_gen| stub_gen(&mut self.machine_st))?; - self.machine_st - .bind(args[1].as_var().unwrap(), stream.into()); + self.machine_st + .bind(args[1].as_var().unwrap(), stream.into()); - Stdio::from(reader) - } - - #[cfg(not(rust_version = "1.87.0"))] - { - Stdio::piped() - } + Stdio::from(reader) } Some(atom!("file")) => { let path = self.machine_st.value_to_str_like(args[1]).unwrap(); @@ -9613,7 +9604,6 @@ impl Machine { #[cfg(feature = "crypto-inpure")] fn rng() -> &'static dyn SecureRandom { - use lazy_static::lazy_static; use std::ops::Deref; static RANDOM: LazyLock = LazyLock::new(SystemRandom::new); diff --git a/tests/scryer/issues.rs b/tests/scryer/issues.rs index 838f4fa4..1cc9a260 100644 --- a/tests/scryer/issues.rs +++ b/tests/scryer/issues.rs @@ -1,6 +1,6 @@ use crate::helper::load_module_test; use crate::helper::load_module_test_with_input; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "http", not(target_arch = "wasm32")))] use crate::helper::load_module_test_with_tokio_runtime_and_input; use serial_test::serial; @@ -164,8 +164,7 @@ fn issue3262_read_from_stdin_no_newline() { } #[test] -#[cfg(feature = "http")] -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "http", not(target_arch = "wasm32")))] #[cfg_attr(miri, ignore = "it takes too long to run")] fn http_open_hanging() { load_module_test_with_tokio_runtime_and_input( From 61ebcdb56e154c939f882017ddc8d8037d320124 Mon Sep 17 00:00:00 2001 From: Skgland Date: Sun, 24 May 2026 23:55:19 +0200 Subject: [PATCH 4/5] fix spelling --- Cargo.toml | 6 +++--- src/machine/system_calls.rs | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5154456c..9c49139d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ default = ["all-simple-cross", "tls", "http"] # currently does not include # ffi due to libffi # tls, http due to openssl -# crypto-inpure due to ring +# crypto-impure due to ring all-pure = ["repl", "hostname"] # enables all features that are simple to get working for cross-compliation # currently all but tls, http as those depend on openssl @@ -34,8 +34,8 @@ hostname = ["dep:hostname"] tls = ["dep:native-tls"] http = ["dep:warp", "dep:reqwest"] # crypto function that require non pure-rust dependencies -crypto-inpure = ["dep:ring"] -crypto-full = ["crypto-inpure"] +crypto-impure = ["dep:ring"] +crypto-full = ["crypto-impure"] [lints.clippy] collapsible_match = "allow" diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 5daa2af8..2954ba39 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -76,7 +76,7 @@ use blake2::{Blake2b512, Blake2s256}; #[cfg(feature = "crypto-full")] use ring::aead; -#[cfg(feature = "crypto-inpure")] +#[cfg(feature = "crypto-impure")] use ring::{ digest, hkdf, hmac, pbkdf2, rand::{SecureRandom, SystemRandom}, @@ -7846,7 +7846,7 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_random_byte(&mut self) { - #[cfg(feature = "crypto-inpure")] + #[cfg(feature = "crypto-impure")] { let arg = self.machine_st.registers[1]; let mut bytes: [u8; 1] = [0]; @@ -7866,7 +7866,7 @@ impl Machine { self.machine_st.unify_fixnum(byte, arg); } - #[cfg(not(feature = "crypto-inpure"))] + #[cfg(not(feature = "crypto-impure"))] { let stub_gen = || functor_stub(atom!("crypto_random_byte"), 1); let err = self.machine_st.missing_feature_error(atom!("crypto")); @@ -8004,7 +8004,7 @@ impl Machine { ) } _ => { - #[cfg(feature = "crypto-inpure")] + #[cfg(feature = "crypto-impure")] { let ints = digest::digest( match algorithm { @@ -8030,7 +8030,7 @@ impl Machine { ) ) } - #[cfg(not(feature = "crypto-inpure"))] + #[cfg(not(feature = "crypto-impure"))] { let stub_gen = || functor_stub(atom!("crypto_data_hash"), 1); let err = self.machine_st.missing_feature_error(atom!("crypto")); @@ -8048,7 +8048,7 @@ impl Machine { pub(crate) fn crypto_hmac(&mut self) { let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3); - #[cfg(feature = "crypto-inpure")] + #[cfg(feature = "crypto-impure")] { let encoding = cell_as_atom!(self.deref_register(2)); let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); @@ -8084,7 +8084,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[4], ints_list); } - #[cfg(not(feature = "crypto-inpure"))] + #[cfg(not(feature = "crypto-impure"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub_gen()); @@ -8096,7 +8096,7 @@ impl Machine { pub(crate) fn crypto_data_hkdf(&mut self) { let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); - #[cfg(feature = "crypto-inpure")] + #[cfg(feature = "crypto-impure")] { let encoding = cell_as_atom!(self.deref_register(2)); let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); @@ -8167,7 +8167,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[7], ints_list); } - #[cfg(not(feature = "crypto-inpure"))] + #[cfg(not(feature = "crypto-impure"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub1_gen()); @@ -8179,7 +8179,7 @@ impl Machine { pub(crate) fn crypto_password_hash(&mut self) { let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3); - #[cfg(feature = "crypto-inpure")] + #[cfg(feature = "crypto-impure")] { use std::num::NonZeroU32; let data = self @@ -8235,7 +8235,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[4], ints_list); } - #[cfg(not(feature = "crypto-inpure"))] + #[cfg(not(feature = "crypto-impure"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub1_gen()); @@ -9602,7 +9602,7 @@ impl Machine { } } -#[cfg(feature = "crypto-inpure")] +#[cfg(feature = "crypto-impure")] fn rng() -> &'static dyn SecureRandom { use std::ops::Deref; @@ -9611,10 +9611,10 @@ fn rng() -> &'static dyn SecureRandom { RANDOM.deref() } -#[cfg(feature = "crypto-inpure")] +#[cfg(feature = "crypto-impure")] struct MyKey(T); -#[cfg(feature = "crypto-inpure")] +#[cfg(feature = "crypto-impure")] impl hkdf::KeyType for MyKey { fn len(&self) -> usize { self.0 From bdba7ba0f5f30de1a28d1aaf5131960cda6b38f3 Mon Sep 17 00:00:00 2001 From: Skgland Date: Mon, 25 May 2026 19:07:20 +0200 Subject: [PATCH 5/5] merge crypto-impure feature into feature crypto-full --- Cargo.toml | 5 ++--- src/machine/system_calls.rs | 30 ++++++++++++++---------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9c49139d..dc17a2d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ default = ["all-simple-cross", "tls", "http"] # currently does not include # ffi due to libffi # tls, http due to openssl -# crypto-impure due to ring +# crypto-full due to ring all-pure = ["repl", "hostname"] # enables all features that are simple to get working for cross-compliation # currently all but tls, http as those depend on openssl @@ -34,8 +34,7 @@ hostname = ["dep:hostname"] tls = ["dep:native-tls"] http = ["dep:warp", "dep:reqwest"] # crypto function that require non pure-rust dependencies -crypto-impure = ["dep:ring"] -crypto-full = ["crypto-impure"] +crypto-full = ["dep:ring"] [lints.clippy] collapsible_match = "allow" diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 2954ba39..2ac93cb7 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -75,10 +75,8 @@ use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use blake2::{Blake2b512, Blake2s256}; #[cfg(feature = "crypto-full")] -use ring::aead; -#[cfg(feature = "crypto-impure")] use ring::{ - digest, hkdf, hmac, pbkdf2, + aead, digest, hkdf, hmac, pbkdf2, rand::{SecureRandom, SystemRandom}, }; @@ -7846,7 +7844,7 @@ impl Machine { #[inline(always)] pub(crate) fn crypto_random_byte(&mut self) { - #[cfg(feature = "crypto-impure")] + #[cfg(feature = "crypto-full")] { let arg = self.machine_st.registers[1]; let mut bytes: [u8; 1] = [0]; @@ -7866,7 +7864,7 @@ impl Machine { self.machine_st.unify_fixnum(byte, arg); } - #[cfg(not(feature = "crypto-impure"))] + #[cfg(not(feature = "crypto-full"))] { let stub_gen = || functor_stub(atom!("crypto_random_byte"), 1); let err = self.machine_st.missing_feature_error(atom!("crypto")); @@ -8004,7 +8002,7 @@ impl Machine { ) } _ => { - #[cfg(feature = "crypto-impure")] + #[cfg(feature = "crypto-full")] { let ints = digest::digest( match algorithm { @@ -8030,7 +8028,7 @@ impl Machine { ) ) } - #[cfg(not(feature = "crypto-impure"))] + #[cfg(not(feature = "crypto-full"))] { let stub_gen = || functor_stub(atom!("crypto_data_hash"), 1); let err = self.machine_st.missing_feature_error(atom!("crypto")); @@ -8048,7 +8046,7 @@ impl Machine { pub(crate) fn crypto_hmac(&mut self) { let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3); - #[cfg(feature = "crypto-impure")] + #[cfg(feature = "crypto-full")] { let encoding = cell_as_atom!(self.deref_register(2)); let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); @@ -8084,7 +8082,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[4], ints_list); } - #[cfg(not(feature = "crypto-impure"))] + #[cfg(not(feature = "crypto-full"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub_gen()); @@ -8096,7 +8094,7 @@ impl Machine { pub(crate) fn crypto_data_hkdf(&mut self) { let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); - #[cfg(feature = "crypto-impure")] + #[cfg(feature = "crypto-full")] { let encoding = cell_as_atom!(self.deref_register(2)); let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding); @@ -8167,7 +8165,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[7], ints_list); } - #[cfg(not(feature = "crypto-impure"))] + #[cfg(not(feature = "crypto-full"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub1_gen()); @@ -8179,7 +8177,7 @@ impl Machine { pub(crate) fn crypto_password_hash(&mut self) { let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3); - #[cfg(feature = "crypto-impure")] + #[cfg(feature = "crypto-full")] { use std::num::NonZeroU32; let data = self @@ -8235,7 +8233,7 @@ impl Machine { unify!(self.machine_st, self.machine_st.registers[4], ints_list); } - #[cfg(not(feature = "crypto-impure"))] + #[cfg(not(feature = "crypto-full"))] { let err = self.machine_st.missing_feature_error(atom!("crypto")); let exception = self.machine_st.error_form(err, stub1_gen()); @@ -9602,7 +9600,7 @@ impl Machine { } } -#[cfg(feature = "crypto-impure")] +#[cfg(feature = "crypto-full")] fn rng() -> &'static dyn SecureRandom { use std::ops::Deref; @@ -9611,10 +9609,10 @@ fn rng() -> &'static dyn SecureRandom { RANDOM.deref() } -#[cfg(feature = "crypto-impure")] +#[cfg(feature = "crypto-full")] struct MyKey(T); -#[cfg(feature = "crypto-impure")] +#[cfg(feature = "crypto-full")] impl hkdf::KeyType for MyKey { fn len(&self) -> usize { self.0