aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-php-shim/src/string.rs143
-rw-r--r--crates/shirabe/src/dependency_resolver/generic_rule.rs17
-rw-r--r--crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs15
-rw-r--r--crates/shirabe/src/package/archiver/phar_archiver.rs26
-rw-r--r--crates/shirabe/src/package/archiver/zip_archiver.rs24
-rw-r--r--crates/shirabe/src/util/no_proxy_pattern.rs137
-rw-r--r--crates/shirabe/tests/dependency_resolver/rule_test.rs9
7 files changed, 81 insertions, 290 deletions
diff --git a/crates/shirabe-php-shim/src/string.rs b/crates/shirabe-php-shim/src/string.rs
index 9563d614..aad5c884 100644
--- a/crates/shirabe-php-shim/src/string.rs
+++ b/crates/shirabe-php-shim/src/string.rs
@@ -598,149 +598,6 @@ fn hex_digit_value(b: u8) -> Option<u8> {
}
}
-pub fn pack(_format: &str, _values: &[PhpMixed]) -> Vec<u8> {
- let fb = _format.as_bytes();
- let mut out: Vec<u8> = Vec::new();
- let mut vi = 0usize;
- let mut i = 0;
- while i < fb.len() {
- let code = fb[i];
- i += 1;
- // Repeat count: a number, '*' (consume the rest), or implicitly 1.
- let mut repeat: usize = 1;
- let mut star = false;
- if i < fb.len() && fb[i] == b'*' {
- star = true;
- i += 1;
- } else {
- let start = i;
- while i < fb.len() && fb[i].is_ascii_digit() {
- i += 1;
- }
- if i > start {
- repeat = _format[start..i].parse().unwrap_or(1);
- }
- }
- match code {
- b'C' | b'c' | b'n' | b'v' | b'N' | b'V' => {
- let count = if star {
- _values.len().saturating_sub(vi)
- } else {
- repeat
- };
- for _ in 0..count {
- let val = crate::intval(_values.get(vi).unwrap_or(&PhpMixed::Null));
- vi += 1;
- match code {
- b'C' | b'c' => out.push(val as u8),
- b'n' => out.extend_from_slice(&(val as u16).to_be_bytes()),
- b'v' => out.extend_from_slice(&(val as u16).to_le_bytes()),
- b'N' => out.extend_from_slice(&(val as u32).to_be_bytes()),
- b'V' => out.extend_from_slice(&(val as u32).to_le_bytes()),
- _ => unreachable!(),
- }
- }
- }
- b'a' | b'A' => {
- let s = crate::php_to_string(_values.get(vi).unwrap_or(&PhpMixed::Null));
- vi += 1;
- let bytes = s.as_bytes();
- let len = if star { bytes.len() } else { repeat };
- let pad = if code == b'A' { b' ' } else { 0 };
- for j in 0..len {
- out.push(bytes.get(j).copied().unwrap_or(pad));
- }
- }
- _ => {
- // TODO(phase-d): only the C/c/n/v/N/V/a/A pack format codes are ported; the
- // machine-size and floating-point codes are not.
- todo!("pack format code {}", code as char)
- }
- }
- }
- out
-}
-
-pub fn unpack(_format: &str, _data: &[u8]) -> Option<IndexMap<String, PhpMixed>> {
- let mut result = IndexMap::new();
- let mut offset = 0usize;
- for group in _format.split('/') {
- if group.is_empty() {
- continue;
- }
- let gb = group.as_bytes();
- let code = gb[0];
- let mut j = 1;
- let mut repeat: usize = 1;
- let mut star = false;
- if j < gb.len() && gb[j] == b'*' {
- star = true;
- j += 1;
- } else {
- let start = j;
- while j < gb.len() && gb[j].is_ascii_digit() {
- j += 1;
- }
- if j > start {
- repeat = group[start..j].parse().unwrap_or(1);
- }
- }
- let name = &group[j..];
- // `i`/`I` are the native int (4 bytes on the LP64 targets in use); `s`/`S` are the native
- // short (2 bytes).
- let size = match code {
- b'C' | b'c' => 1,
- b'n' | b'v' | b's' | b'S' => 2,
- b'N' | b'V' | b'i' | b'I' => 4,
- _ => {
- // TODO(phase-d): only C/c/n/v/N/V/s/S/i/I unpack format codes are ported; the
- // machine-size long/quad and floating-point codes are not.
- todo!("unpack format code {}", code as char)
- }
- };
- let count = if star {
- _data.len().saturating_sub(offset) / size
- } else {
- repeat
- };
- for idx in 0..count {
- if offset + size > _data.len() {
- break;
- }
- let chunk = &_data[offset..offset + size];
- offset += size;
- let value: i64 = match code {
- b'C' => chunk[0] as i64,
- b'c' => chunk[0] as i8 as i64,
- b'n' => u16::from_be_bytes([chunk[0], chunk[1]]) as i64,
- b'v' => u16::from_le_bytes([chunk[0], chunk[1]]) as i64,
- b's' => i16::from_ne_bytes([chunk[0], chunk[1]]) as i64,
- b'S' => u16::from_ne_bytes([chunk[0], chunk[1]]) as i64,
- b'N' => u32::from_be_bytes(chunk.try_into().unwrap()) as i64,
- b'V' => u32::from_le_bytes(chunk.try_into().unwrap()) as i64,
- b'i' => i32::from_ne_bytes(chunk.try_into().unwrap()) as i64,
- b'I' => u32::from_ne_bytes(chunk.try_into().unwrap()) as i64,
- _ => unreachable!(),
- };
- // PHP keys: "name" for a single element; "name1", "name2", ... for repeats; the 1-based
- // index alone when the name is empty.
- let key = if star || repeat > 1 {
- if name.is_empty() {
- (idx + 1).to_string()
- } else {
- format!("{}{}", name, idx + 1)
- }
- } else if name.is_empty() {
- "1".to_string()
- } else {
- name.to_string()
- };
- result.insert(key, PhpMixed::Int(value));
- }
- }
- Some(result)
-}
-
pub fn sscanf(_subject: &str, _format: &str, _a: &mut i64, _b: &mut i64) -> i64 {
// TODO(phase-d): a general sscanf format-string parser is not ported; this specialized two-int
// overload has no current callers.
diff --git a/crates/shirabe/src/dependency_resolver/generic_rule.rs b/crates/shirabe/src/dependency_resolver/generic_rule.rs
index 328a770d..8b64dc46 100644
--- a/crates/shirabe/src/dependency_resolver/generic_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/generic_rule.rs
@@ -2,7 +2,7 @@
use super::rule::ReasonData;
use crate::dependency_resolver::{Rule, RuleBase};
-use shirabe_php_shim::{PHP_VERSION_ID, RuntimeException, hash_raw, unpack};
+use shirabe_php_shim::{PHP_VERSION_ID, RuntimeException, hash_raw};
#[derive(Debug)]
pub struct GenericRule {
@@ -42,19 +42,8 @@ impl GenericRule {
"sha1"
};
let binary = hash_raw(algo, &joined);
- let data = unpack("ihash", &binary);
- match data {
- Some(map) => {
- if let Some(val) = map.get("hash") {
- Ok(val.as_int().unwrap_or(0))
- } else {
- Err(RuntimeException {
- message: format!("Failed unpacking: {}", joined),
- code: 0,
- }
- .into())
- }
- }
+ match binary.get(..4) {
+ Some(chunk) => Ok(i32::from_ne_bytes(chunk.try_into().unwrap()) as i64),
None => Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
diff --git a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
index bfbfc82a..0936dd0c 100644
--- a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
@@ -57,19 +57,8 @@ impl MultiConflictRule {
"sha1"
};
let binary = hash_raw(algo, &format!("c:{}", joined));
- let data = shirabe_php_shim::unpack("ihash", &binary);
- match data {
- Some(map) => {
- if let Some(val) = map.get("hash") {
- Ok(val.as_int().unwrap_or(0))
- } else {
- Err(RuntimeException {
- message: format!("Failed unpacking: {}", joined),
- code: 0,
- }
- .into())
- }
- }
+ match binary.get(..4) {
+ Some(chunk) => Ok(i32::from_ne_bytes(chunk.try_into().unwrap()) as i64),
None => Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
diff --git a/crates/shirabe/src/package/archiver/phar_archiver.rs b/crates/shirabe/src/package/archiver/phar_archiver.rs
index 55e4cb95..fbab8c67 100644
--- a/crates/shirabe/src/package/archiver/phar_archiver.rs
+++ b/crates/shirabe/src/package/archiver/phar_archiver.rs
@@ -5,8 +5,8 @@ use crate::package::archiver::ArchivableFilesFinder;
use crate::package::archiver::ArchiverInterface;
use indexmap::IndexMap;
use shirabe_php_shim::{
- FilesystemIterator, Phar, PharData, PhpMixed, RuntimeException, bzcompress, file_exists,
- file_put_contents, function_exists, gzcompress, pack, str_repeat, strrpos, unlink,
+ FilesystemIterator, Phar, PharData, RuntimeException, bzcompress, file_exists,
+ file_put_contents, function_exists, gzcompress, str_repeat, strrpos, unlink,
};
fn formats() -> IndexMap<&'static str, i64> {
@@ -88,19 +88,15 @@ impl ArchiverInterface for PharArchiver {
file_put_contents(&target, &str_repeat("\0", 10240).into_bytes());
} else if format == "zip" {
// create minimal valid ZIP file (Empty Central Directory + End of Central Directory record)
- let eocd = pack(
- "VvvvvVVv",
- &[
- PhpMixed::Int(0x06054b50), // End of central directory signature
- PhpMixed::Int(0), // Number of this disk
- PhpMixed::Int(0), // Disk where central directory starts
- PhpMixed::Int(0), // Number of central directory records on this disk
- PhpMixed::Int(0), // Total number of central directory records
- PhpMixed::Int(0), // Size of central directory (bytes)
- PhpMixed::Int(0), // Offset of start of central directory
- PhpMixed::Int(0), // Comment length
- ],
- );
+ let mut eocd = Vec::with_capacity(22);
+ eocd.extend_from_slice(&0x06054b50u32.to_le_bytes()); // End of central directory signature
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Number of this disk
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Disk where central directory starts
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Number of central directory records on this disk
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Total number of central directory records
+ eocd.extend_from_slice(&0u32.to_le_bytes()); // Size of central directory (bytes)
+ eocd.extend_from_slice(&0u32.to_le_bytes()); // Offset of start of central directory
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Comment length
file_put_contents(&target, &eocd);
} else if format == "tar.gz" || format == "tar.bz2" {
let compress_algo = *compress_formats.get(format.as_str()).unwrap();
diff --git a/crates/shirabe/src/package/archiver/zip_archiver.rs b/crates/shirabe/src/package/archiver/zip_archiver.rs
index 41201b56..bf0144fb 100644
--- a/crates/shirabe/src/package/archiver/zip_archiver.rs
+++ b/crates/shirabe/src/package/archiver/zip_archiver.rs
@@ -6,7 +6,7 @@ use crate::util::Filesystem;
use crate::util::Platform;
use indexmap::IndexMap;
use shirabe_php_shim::{
- PhpMixed, RuntimeException, ZipArchive, class_exists, fileperms, method_exists, pack, realpath,
+ PhpMixed, RuntimeException, ZipArchive, class_exists, fileperms, method_exists, realpath,
};
use std::path::PathBuf;
@@ -93,19 +93,15 @@ impl ArchiverInterface for ZipArchiver {
if zip.close() {
if !std::path::Path::new(&target).exists() {
// create minimal valid ZIP file (Empty Central Directory + End of Central Directory record)
- let eocd = pack(
- "VvvvvVVv",
- &[
- PhpMixed::Int(0x06054b50), // End of central directory signature
- PhpMixed::Int(0), // Number of this disk
- PhpMixed::Int(0), // Disk where central directory starts
- PhpMixed::Int(0), // Number of central directory records on this disk
- PhpMixed::Int(0), // Total number of central directory records
- PhpMixed::Int(0), // Size of central directory (bytes)
- PhpMixed::Int(0), // Offset of start of central directory
- PhpMixed::Int(0), // Comment length
- ],
- );
+ let mut eocd = Vec::with_capacity(22);
+ eocd.extend_from_slice(&0x06054b50u32.to_le_bytes()); // End of central directory signature
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Number of this disk
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Disk where central directory starts
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Number of central directory records on this disk
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Total number of central directory records
+ eocd.extend_from_slice(&0u32.to_le_bytes()); // Size of central directory (bytes)
+ eocd.extend_from_slice(&0u32.to_le_bytes()); // Offset of start of central directory
+ eocd.extend_from_slice(&0u16.to_le_bytes()); // Comment length
std::fs::write(&target, &eocd)?;
}
diff --git a/crates/shirabe/src/util/no_proxy_pattern.rs b/crates/shirabe/src/util/no_proxy_pattern.rs
index a33f2451..5ece7942 100644
--- a/crates/shirabe/src/util/no_proxy_pattern.rs
+++ b/crates/shirabe/src/util/no_proxy_pattern.rs
@@ -5,7 +5,7 @@ use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{
PHP_URL_HOST, PHP_URL_PORT, PHP_URL_SCHEME, PhpMixed, RuntimeException, array_key_exists,
empty, explode, filter_var_int_with_range, filter_var_ip, inet_pton, ltrim, parse_url,
- php_regex, stripos, strlen, strpbrk, strpos, substr, substr_count, unpack,
+ php_regex, stripos, strlen, strpbrk, strpos, substr, substr_count,
};
/// Tests URLs against NO_PROXY patterns
@@ -151,60 +151,38 @@ impl NoProxyPattern {
/// Returns true if the target ip is in the network range
pub(crate) fn match_range(&self, network: &IpData, target: &IpData) -> anyhow::Result<bool> {
- let net = unpack("C*", &network.ip);
- let mask = unpack("C*", network.netmask.as_deref().unwrap_or_default());
- let ip = unpack("C*", &target.ip);
- let net = match net {
- Some(n) => n,
- None => {
- return Err(RuntimeException {
- message: format!(
- "Could not parse network IP {}",
- String::from_utf8_lossy(&network.ip)
- ),
- code: 0,
- }
- .into());
+ let net = network.ip.as_slice();
+ let mask = network.netmask.as_deref().unwrap_or_default();
+ let ip = target.ip.as_slice();
+ if net.is_empty() {
+ return Err(RuntimeException {
+ message: format!(
+ "Could not parse network IP {}",
+ String::from_utf8_lossy(net)
+ ),
+ code: 0,
}
- };
- let mask = match mask {
- Some(m) => m,
- None => {
- return Err(RuntimeException {
- message: format!(
- "Could not parse netmask {}",
- String::from_utf8_lossy(network.netmask.as_deref().unwrap_or_default())
- ),
- code: 0,
- }
- .into());
+ .into());
+ }
+ if mask.is_empty() {
+ return Err(RuntimeException {
+ message: format!("Could not parse netmask {}", String::from_utf8_lossy(mask)),
+ code: 0,
}
- };
- let ip = match ip {
- Some(i) => i,
- None => {
- return Err(RuntimeException {
- message: format!(
- "Could not parse target IP {}",
- String::from_utf8_lossy(&target.ip)
- ),
- code: 0,
- }
- .into());
+ .into());
+ }
+ if ip.is_empty() {
+ return Err(RuntimeException {
+ message: format!("Could not parse target IP {}", String::from_utf8_lossy(ip)),
+ code: 0,
}
- };
+ .into());
+ }
- // PHP: for ($i = 1; $i < 17; ++$i)
- for i in 1..17 {
- let net_byte = net
- .get(&i.to_string())
- .and_then(|v| v.as_int())
- .unwrap_or(0);
- let mask_byte = mask
- .get(&i.to_string())
- .and_then(|v| v.as_int())
- .unwrap_or(0);
- let ip_byte = ip.get(&i.to_string()).and_then(|v| v.as_int()).unwrap_or(0);
+ for i in 0..16 {
+ let net_byte = net.get(i).copied().unwrap_or(0);
+ let mask_byte = mask.get(i).copied().unwrap_or(0);
+ let ip_byte = ip.get(i).copied().unwrap_or(0);
if (net_byte & mask_byte) != (ip_byte & mask_byte) {
return Ok(false);
}
@@ -350,43 +328,32 @@ impl NoProxyPattern {
let netmask = self.ip_get_mask(prefix, size);
// Get the network from the address and mask
- let mask = unpack("C*", &netmask);
- let ip = unpack("C*", range_ip);
- let mut net: Vec<u8> = vec![];
- let mask = match mask {
- Some(m) => m,
- None => {
- return Err(RuntimeException {
- message: format!(
- "Could not parse netmask {}",
- String::from_utf8_lossy(&netmask)
- ),
- code: 0,
- }
- .into());
+ if netmask.is_empty() {
+ return Err(RuntimeException {
+ message: format!(
+ "Could not parse netmask {}",
+ String::from_utf8_lossy(&netmask)
+ ),
+ code: 0,
}
- };
- let ip = match ip {
- Some(i) => i,
- None => {
- return Err(RuntimeException {
- message: format!(
- "Could not parse range IP {}",
- String::from_utf8_lossy(range_ip)
- ),
- code: 0,
- }
- .into());
+ .into());
+ }
+ if range_ip.is_empty() {
+ return Err(RuntimeException {
+ message: format!(
+ "Could not parse range IP {}",
+ String::from_utf8_lossy(range_ip)
+ ),
+ code: 0,
}
- };
+ .into());
+ }
- for i in 1..17 {
- let ip_byte = ip.get(&i.to_string()).and_then(|v| v.as_int()).unwrap_or(0);
- let mask_byte = mask
- .get(&i.to_string())
- .and_then(|v| v.as_int())
- .unwrap_or(0);
- net.push((ip_byte & mask_byte) as u8);
+ let mut net: Vec<u8> = Vec::with_capacity(16);
+ for i in 0..16 {
+ let ip_byte = range_ip.get(i).copied().unwrap_or(0);
+ let mask_byte = netmask.get(i).copied().unwrap_or(0);
+ net.push(ip_byte & mask_byte);
}
Ok((net, netmask))
diff --git a/crates/shirabe/tests/dependency_resolver/rule_test.rs b/crates/shirabe/tests/dependency_resolver/rule_test.rs
index 6bfb7bd1..9526bf39 100644
--- a/crates/shirabe/tests/dependency_resolver/rule_test.rs
+++ b/crates/shirabe/tests/dependency_resolver/rule_test.rs
@@ -7,7 +7,7 @@ use shirabe::dependency_resolver::{
};
use shirabe::package::Link;
use shirabe::repository::RepositorySet;
-use shirabe_php_shim::{PHP_VERSION_ID, hash_raw, unpack};
+use shirabe_php_shim::{PHP_VERSION_ID, hash_raw};
use shirabe_semver::constraint::MatchAllConstraint;
fn root_require_reason() -> ReasonData {
@@ -35,12 +35,9 @@ fn test_get_hash() {
"sha1"
};
let binary = hash_raw(algo, "123");
- let hash = unpack("ihash", &binary).unwrap();
+ let hash = i32::from_ne_bytes(binary[..4].try_into().unwrap()) as i64;
- assert_eq!(
- hash.get("hash").unwrap().as_int(),
- rule.get_hash().unwrap().as_int()
- );
+ assert_eq!(Some(hash), rule.get_hash().unwrap().as_int());
}
#[test]