diff options
| -rw-r--r-- | Cargo.lock | 7 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/lib.rs | 10 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/random.rs | 32 | ||||
| -rw-r--r-- | crates/shirabe/src/cache.rs | 2 | ||||
| -rw-r--r-- | crates/shirabe/src/downloader/zip_downloader.rs | 2 |
7 files changed, 45 insertions, 10 deletions
@@ -305,6 +305,12 @@ dependencies = [ ] [[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1013,6 +1019,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", + "fastrand", "indexmap", "regex", "serde", @@ -16,6 +16,7 @@ anyhow = "1.0.102" async-trait = "0.1.89" base64 = "0.22.1" chrono = { version = "0.4.44", features = ["serde"] } +fastrand = "2.4.1" indexmap = { version = "2.14.0", features = ["serde"] } md5 = "0.7.0" regex = "1.12.3" diff --git a/crates/shirabe-php-shim/Cargo.toml b/crates/shirabe-php-shim/Cargo.toml index ac2003a..b577c1f 100644 --- a/crates/shirabe-php-shim/Cargo.toml +++ b/crates/shirabe-php-shim/Cargo.toml @@ -6,6 +6,7 @@ edition.workspace = true [dependencies] anyhow.workspace = true chrono.workspace = true +fastrand.workspace = true indexmap.workspace = true regex.workspace = true serde.workspace = true diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs index 2a6ecf6..c236727 100644 --- a/crates/shirabe-php-shim/src/lib.rs +++ b/crates/shirabe-php-shim/src/lib.rs @@ -1,6 +1,8 @@ mod preg; +mod random; pub use preg::*; +pub use random::*; use indexmap::IndexMap; @@ -1360,10 +1362,6 @@ pub fn filesize(_path: &str) -> Option<i64> { std::fs::metadata(_path).ok().map(|m| m.len() as i64) } -pub fn random_int(_min: i64, _max: i64) -> i64 { - todo!() -} - pub fn json_encode_ex<T: serde::Serialize + ?Sized>(_value: &T, _flags: i64) -> Option<String> { todo!() } @@ -1607,10 +1605,6 @@ pub fn bin2hex(_data: &[u8]) -> String { _data.iter().map(|b| format!("{:02x}", b)).collect() } -pub fn random_bytes(_length: usize) -> Vec<u8> { - todo!() -} - pub fn is_dir(_path: &str) -> bool { std::path::Path::new(_path).is_dir() } diff --git a/crates/shirabe-php-shim/src/random.rs b/crates/shirabe-php-shim/src/random.rs new file mode 100644 index 0000000..05f62bd --- /dev/null +++ b/crates/shirabe-php-shim/src/random.rs @@ -0,0 +1,32 @@ +//! PHP's `random_int()` and `random_bytes()` are cryptographically secure; +//! these are not. Composer does not rely on that property, so a +//! non-cryptographic PRNG is sufficient here. + +pub fn random_int<T: RandomInt>(range: impl std::ops::RangeBounds<T>) -> T { + T::random_int(range) +} + +pub fn random_bytes(len: usize) -> Vec<u8> { + let mut buf = vec![0u8; len]; + fastrand::fill(&mut buf); + buf +} + +/// Integral types for which [`random_int`] can generate a value. +pub trait RandomInt: Sized { + fn random_int(range: impl std::ops::RangeBounds<Self>) -> Self; +} + +macro_rules! impl_random_int { + ($($t:ident),* $(,)?) => { + $( + impl RandomInt for $t { + fn random_int(range: impl std::ops::RangeBounds<Self>) -> Self { + fastrand::$t(range) + } + } + )* + }; +} + +impl_random_int!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); diff --git a/crates/shirabe/src/cache.rs b/crates/shirabe/src/cache.rs index a193d0b..636a8ed 100644 --- a/crates/shirabe/src/cache.rs +++ b/crates/shirabe/src/cache.rs @@ -267,7 +267,7 @@ impl Cache { return false; } - random_int(0, 50) == 0 + random_int(0..50) == 0 } pub fn remove(&mut self, file: &str) -> bool { diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs index d4ec2ab..2eb7b94 100644 --- a/crates/shirabe/src/downloader/zip_downloader.rs +++ b/crates/shirabe/src/downloader/zip_downloader.rs @@ -307,7 +307,7 @@ impl ZipDownloader { let stat_index = if inspect_all { i } else { - random_int(0, total_files - 1) + random_int(0..total_files) }; if let Some(stat) = zip_archive.stat_index(stat_index) { let size = stat.get("size").and_then(|v| v.as_int()).unwrap_or(0); |
