forked from mirrors/kingfisher
Release binary trimmed from 34 MB to 26 MB (~24% smaller). Switched jsonwebtoken to its rust_crypto backend (eliminates our scanner's pull on aws-lc-rs), bumped workspace hmac 0.12→0.13, sha1 0.10→0.11, sha2 0.10→0.11 to deduplicate our internal crypto code with the AWS sigv4 side, and migrated affected call sites in kingfisher-core, kingfisher-rules, and kingfisher-scanner to the digest-0.11 API (hex::encode for hex digests, explicit KeyInit import for HMAC).
This commit is contained in:
parent
34b5c48888
commit
31663b03b5
19 changed files with 143 additions and 63 deletions
|
|
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Git repository scans now extract archive blobs encountered in the object database, not just on the filesystem. Previously a `.zip`/`.jar`/`.apk`/`.tar.gz` committed to a repo was scanned as raw compressed bytes, so secrets inside it were invisible. The git enumerator fans each archive entry out as a synthetic `<archive>!<entry>` blob with the original commit metadata. Honors `--no-extract-archives` for opt-out.
|
||||
- Performance: ZIP-based git blobs ≤ 64 MB extract entirely in memory (no temp-file round trip), beating the v1.99.0 baseline by ~15% on a 80 GiB monorepo despite scanning ~300K additional archive-content blobs. Larger archives auto-fall-back to a disk-streaming extractor.
|
||||
- Memory safety: hard caps on archive extraction — 64 MB compressed pre-flight, 256 MB aggregate decompressed per archive (in-memory and disk paths), 512 MB per entry, plus a `PK\x03\x04` magic-byte gate. Worst-case footprint is bounded at ~`num_jobs * 320 MB`.
|
||||
- Release binary trimmed from 34 MB to 26 MB (~24% smaller). Switched `jsonwebtoken` to its `rust_crypto` backend (eliminates our scanner's pull on `aws-lc-rs`), bumped workspace `hmac` 0.12→0.13, `sha1` 0.10→0.11, `sha2` 0.10→0.11 to deduplicate our internal crypto code with the AWS sigv4 side, and migrated affected call sites in `kingfisher-core`, `kingfisher-rules`, and `kingfisher-scanner` to the digest-0.11 API (`hex::encode` for hex digests, explicit `KeyInit` import for HMAC).
|
||||
|
||||
## [v1.99.0]
|
||||
- Fixed [#371](https://github.com/mongodb/kingfisher/issues/371): `pip install kingfisher-bin` on glibc Linux distros (Ubuntu, Debian, RHEL, Fedora, …) installed a macOS Mach-O binary and failed with `OSError: [Errno 8] Exec format error`. Linux wheels are now tagged `manylinux_2_17_<arch>.musllinux_1_2_<arch>` (instead of `musllinux_1_2_<arch>` only), so pip accepts them on both glibc-2.17+ and musl distros. The `pypi/hatch_build.py` hook now hard-fails when `KINGFISHER_PYPI_WHEEL_TAG` is unset, and the publish workflow refuses to upload any `py3-none-any.whl`, so the v1.92.0-era pure-Python wheel cannot recur.
|
||||
|
|
|
|||
106
Cargo.lock
generated
106
Cargo.lock
generated
|
|
@ -1883,7 +1883,7 @@ dependencies = [
|
|||
"crc",
|
||||
"digest 0.10.7",
|
||||
"rustversion",
|
||||
"spin",
|
||||
"spin 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2510,6 +2510,7 @@ dependencies = [
|
|||
"ff",
|
||||
"generic-array",
|
||||
"group",
|
||||
"hkdf",
|
||||
"pem-rfc7468",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
|
|
@ -4251,6 +4252,15 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hkdf"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
|
||||
dependencies = [
|
||||
"hmac 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
|
|
@ -4953,11 +4963,18 @@ checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1"
|
|||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"base64 0.22.1",
|
||||
"ed25519-dalek",
|
||||
"getrandom 0.2.17",
|
||||
"hmac 0.12.1",
|
||||
"js-sys",
|
||||
"p256",
|
||||
"p384",
|
||||
"pem",
|
||||
"rand 0.8.6",
|
||||
"rsa",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.9",
|
||||
"signature",
|
||||
"simple_asn1",
|
||||
]
|
||||
|
|
@ -5072,7 +5089,7 @@ dependencies = [
|
|||
"serde-sarif",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sha1 0.10.6",
|
||||
"sha1 0.11.0",
|
||||
"sha2 0.11.0",
|
||||
"smallvec",
|
||||
"strum 0.28.0",
|
||||
|
|
@ -5124,7 +5141,7 @@ dependencies = [
|
|||
"schemars 0.8.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha1 0.10.6",
|
||||
"sha1 0.11.0",
|
||||
"smallvec",
|
||||
"thiserror 2.0.18",
|
||||
"tokei",
|
||||
|
|
@ -5138,7 +5155,8 @@ dependencies = [
|
|||
"base32",
|
||||
"base64 0.22.1",
|
||||
"crc32fast",
|
||||
"hmac 0.12.1",
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"ignore",
|
||||
"include_dir",
|
||||
"kingfisher-core",
|
||||
|
|
@ -5153,8 +5171,8 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sha1 0.10.6",
|
||||
"sha2 0.10.9",
|
||||
"sha1 0.11.0",
|
||||
"sha2 0.11.0",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing",
|
||||
|
|
@ -5185,7 +5203,7 @@ dependencies = [
|
|||
"crossbeam-skiplist",
|
||||
"ed25519-dalek",
|
||||
"hex",
|
||||
"hmac 0.12.1",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.0",
|
||||
"jsonwebtoken 10.3.0",
|
||||
"kingfisher-core",
|
||||
|
|
@ -5211,8 +5229,8 @@ dependencies = [
|
|||
"schemars 0.8.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha1 0.10.6",
|
||||
"sha2 0.10.9",
|
||||
"sha1 0.11.0",
|
||||
"sha2 0.11.0",
|
||||
"smallvec",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
|
|
@ -5258,6 +5276,9 @@ name = "lazy_static"
|
|||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lber"
|
||||
|
|
@ -5920,6 +5941,23 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"libm",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand 0.8.6",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
|
|
@ -5983,6 +6021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6237,6 +6276,18 @@ dependencies = [
|
|||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "p384"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2 0.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
|
|
@ -6517,6 +6568,17 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
|
|
@ -7312,6 +7374,26 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
|
||||
dependencies = [
|
||||
"const-oid 0.9.6",
|
||||
"digest 0.10.7",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsqlite-vfs"
|
||||
version = "0.1.0"
|
||||
|
|
@ -8070,6 +8152,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.10.0"
|
||||
|
|
|
|||
12
Cargo.toml
12
Cargo.toml
|
|
@ -32,9 +32,9 @@ xxhash-rust = { version = "0.8", features = ["xxh3"] }
|
|||
ignore = "0.4"
|
||||
walkdir = "2.5"
|
||||
include_dir = "0.7"
|
||||
sha1 = "0.10"
|
||||
sha2 = "0.10"
|
||||
hmac = "0.12"
|
||||
sha1 = "0.11"
|
||||
sha2 = "0.11"
|
||||
hmac = "0.13"
|
||||
base32 = "0.5.1"
|
||||
base64 = "0.22"
|
||||
percent-encoding = "2.3"
|
||||
|
|
@ -181,9 +181,9 @@ futures = "0.3.31"
|
|||
dashmap = "6.1.0"
|
||||
xxhash-rust = { version = "0.8.15", features = ["xxh3", "const_xxh3"] }
|
||||
serde_yaml = "0.9.34"
|
||||
hmac = "0.13.0"
|
||||
hmac = { workspace = true }
|
||||
sha1 = { workspace = true }
|
||||
sha2 = "0.11.0"
|
||||
sha2 = { workspace = true }
|
||||
humantime = "2.3.0"
|
||||
path-dedot = "3.1.1"
|
||||
quick-xml = { version = "0.39.2", features = ["serde", "serialize"] }
|
||||
|
|
@ -252,7 +252,7 @@ proptest = "1.9.0"
|
|||
[profile.release]
|
||||
debug = false
|
||||
strip = true
|
||||
opt-level = 3 # Maximum optimization for performance
|
||||
opt-level = "s" #3 # Maximum optimization for performance
|
||||
lto = true # Enable Link Time Optimization
|
||||
codegen-units = 1 # Optimize for size but slower compilation
|
||||
panic = "abort" # Remove unwind tables for panics
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
use std::{
|
||||
convert::TryInto,
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
io::Read,
|
||||
path::Path,
|
||||
sync::{
|
||||
Arc, OnceLock,
|
||||
|
|
@ -235,7 +235,7 @@ impl BlobId {
|
|||
pub fn new(input: &[u8]) -> Self {
|
||||
const CHUNK: usize = 64 * 1024; // 64KB from start and end
|
||||
let mut hasher = Sha1::new();
|
||||
write!(&mut hasher, "blob {}\0", input.len()).unwrap();
|
||||
hasher.update(format!("blob {}\0", input.len()).as_bytes());
|
||||
if input.len() <= CHUNK * 2 {
|
||||
hasher.update(input);
|
||||
} else {
|
||||
|
|
@ -249,7 +249,7 @@ impl BlobId {
|
|||
/// Computes a `BlobId` from the complete bytes (no truncation).
|
||||
pub fn compute_from_bytes(bytes: &[u8]) -> Self {
|
||||
let mut hasher = Sha1::new();
|
||||
write!(&mut hasher, "blob {}\0", bytes.len()).unwrap();
|
||||
hasher.update(format!("blob {}\0", bytes.len()).as_bytes());
|
||||
hasher.update(bytes);
|
||||
let digest: [u8; 20] = hasher.finalize().into();
|
||||
BlobId(digest)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ crc32fast = "1.5"
|
|||
hmac.workspace = true
|
||||
sha1.workspace = true
|
||||
sha2.workspace = true
|
||||
hex.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
time.workspace = true
|
||||
uuid = { workspace = true, features = ["v4"] }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use base64::{Engine, engine::general_purpose};
|
||||
use crc32fast::Hasher;
|
||||
use hmac::{Hmac, Mac};
|
||||
use hmac::{Hmac, KeyInit, Mac};
|
||||
use liquid_core::{
|
||||
Display_filter, Error as LiquidError, Expression, Filter, FilterParameters, FilterReflection,
|
||||
FromFilterParameters, ParseFilter, Result, Runtime, Value, ValueView,
|
||||
|
|
@ -536,7 +536,7 @@ static_filter!(
|
|||
|input: &dyn ValueView| -> String {
|
||||
let mut h = Sha256::new();
|
||||
h.update(input.to_kstr().as_bytes());
|
||||
format!("{:x}", h.finalize())
|
||||
hex::encode(h.finalize())
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -1128,7 +1128,7 @@ pub fn register_all(builder: liquid::ParserBuilder) -> liquid::ParserBuilder {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base64::{Engine as _, engine::general_purpose};
|
||||
use hmac::{Hmac, Mac};
|
||||
use hmac::{Hmac, KeyInit, Mac};
|
||||
use liquid::{ParserBuilder, object};
|
||||
use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
|
||||
use regex::Regex;
|
||||
|
|
@ -1162,7 +1162,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn sha256_filter() {
|
||||
let expect = format!("{:x}", Sha256::digest(b"hello"));
|
||||
let expect = hex::encode(Sha256::digest(b"hello"));
|
||||
assert_eq!(render(r#"{{ "hello" | sha256 }}"#), expect);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ pem = { version = "3.0.6", optional = true }
|
|||
percent-encoding = { workspace = true, optional = true }
|
||||
ring = { version = "0.17", optional = true }
|
||||
|
||||
jsonwebtoken = { version = "10.3.0", features = ["aws-lc-rs"], optional = true }
|
||||
jsonwebtoken = { version = "10.3.0", default-features = false, features = ["rust_crypto"], optional = true }
|
||||
p256 = { version = "0.13.2", optional = true }
|
||||
ed25519-dalek = { version = "2.2", features = ["pkcs8"], optional = true }
|
||||
hex = { workspace = true, optional = true }
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ pub fn generate_aws_cache_key(aws_access_key_id: &str, aws_secret_access_key: &s
|
|||
hasher.update(aws_access_key_id.as_bytes());
|
||||
hasher.update(b"\0");
|
||||
hasher.update(aws_secret_access_key.as_bytes());
|
||||
format!("AWS:{:x}", hasher.finalize())
|
||||
format!("AWS:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
||||
/// Validate AWS credentials format before attempting validation.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
|||
use anyhow::{Result, anyhow};
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD as b64};
|
||||
use chrono::Utc;
|
||||
use hmac::{Hmac, Mac};
|
||||
use hmac::{Hmac, KeyInit, Mac};
|
||||
use http::StatusCode;
|
||||
use quick_xml::{Reader, events::Event};
|
||||
use reqwest::{Client, header::HeaderValue};
|
||||
|
|
@ -18,7 +18,7 @@ pub fn generate_azure_cache_key(azure_json: &str) -> String {
|
|||
use sha1::{Digest, Sha1};
|
||||
let mut h = Sha1::new();
|
||||
h.update(azure_json.as_bytes());
|
||||
format!("AZURE:{:x}", h.finalize())
|
||||
format!("AZURE:{}", hex::encode(h.finalize()))
|
||||
}
|
||||
|
||||
/// Validate Azure Storage credentials without Azure SDK crates.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub fn generate_coinbase_cache_key(cred_name: &str, private_key: &str) -> String
|
|||
h.update(cred_name.as_bytes());
|
||||
h.update(b"\0");
|
||||
h.update(private_key.as_bytes());
|
||||
format!("COINBASE:{:x}", h.finalize())
|
||||
format!("COINBASE:{}", hex::encode(h.finalize()))
|
||||
}
|
||||
|
||||
pub async fn validate_cdp_api_key(
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ pub fn generate_gcp_cache_key(gcp_json: &str) -> String {
|
|||
use sha1::{Digest, Sha1};
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(gcp_json.as_bytes());
|
||||
format!("GCP:{:x}", hasher.finalize())
|
||||
format!("GCP:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
||||
impl GcpValidator {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ pub fn generate_http_cache_key_parts(
|
|||
hasher.update(b"\0");
|
||||
}
|
||||
|
||||
format!("HTTP:{:x}", hasher.finalize())
|
||||
format!("HTTP:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
||||
/// Parse an HTTP method from a string.
|
||||
|
|
|
|||
|
|
@ -147,5 +147,5 @@ pub fn generate_mongodb_cache_key(mongodb_uri: &str) -> String {
|
|||
use sha1::{Digest, Sha1};
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(mongodb_uri.as_bytes());
|
||||
format!("MongoDB:{:x}", hasher.finalize())
|
||||
format!("MongoDB:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ pub fn generate_mysql_cache_key(mysql_url: &str) -> String {
|
|||
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(mysql_url.as_bytes());
|
||||
format!("MySQL:{:x}", hasher.finalize())
|
||||
format!("MySQL:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
||||
fn is_local_host(host: &str) -> bool {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl ServerCertVerifier for LaxCertVerifier {
|
|||
pub fn generate_postgres_cache_key(postgres_url: &str) -> String {
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(postgres_url.as_bytes());
|
||||
format!("Postgres:{:x}", hasher.finalize())
|
||||
format!("Postgres:{}", hex::encode(hasher.finalize()))
|
||||
}
|
||||
|
||||
pub fn parse_postgres_url(postgres_url: &str) -> Result<Config> {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,13 @@ description: "Kingfisher release history: new features, rules, bug fixes, and im
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [v1.100.0]
|
||||
- Archive scanning now reaches inside Android/iOS app packages: added `apk`, `aab`, and `ipa` to the recognized ZIP-based archive formats so secrets embedded in APK/AAB/IPA contents (e.g. `classes*.dex`, `res/values/strings.xml`) are extracted and matched.
|
||||
- Git repository scans now extract archive blobs encountered in the object database, not just on the filesystem. Previously a `.zip`/`.jar`/`.apk`/`.tar.gz` committed to a repo was scanned as raw compressed bytes, so secrets inside it were invisible. The git enumerator fans each archive entry out as a synthetic `<archive>!<entry>` blob with the original commit metadata. Honors `--no-extract-archives` for opt-out.
|
||||
- Performance: ZIP-based git blobs ≤ 64 MB extract entirely in memory (no temp-file round trip), beating the v1.99.0 baseline by ~15% on a 80 GiB monorepo despite scanning ~300K additional archive-content blobs. Larger archives auto-fall-back to a disk-streaming extractor.
|
||||
- Memory safety: hard caps on archive extraction — 64 MB compressed pre-flight, 256 MB aggregate decompressed per archive (in-memory and disk paths), 512 MB per entry, plus a `PK\x03\x04` magic-byte gate. Worst-case footprint is bounded at ~`num_jobs * 320 MB`.
|
||||
- Release binary trimmed from 34 MB to 26 MB (~24% smaller). Switched `jsonwebtoken` to its `rust_crypto` backend (eliminates our scanner's pull on `aws-lc-rs`), bumped workspace `hmac` 0.12→0.13, `sha1` 0.10→0.11, `sha2` 0.10→0.11 to deduplicate our internal crypto code with the AWS sigv4 side, and migrated affected call sites in `kingfisher-core`, `kingfisher-rules`, and `kingfisher-scanner` to the digest-0.11 API (`hex::encode` for hex digests, explicit `KeyInit` import for HMAC).
|
||||
|
||||
## [v1.99.0]
|
||||
- Fixed [#371](https://github.com/mongodb/kingfisher/issues/371): `pip install kingfisher-bin` on glibc Linux distros (Ubuntu, Debian, RHEL, Fedora, …) installed a macOS Mach-O binary and failed with `OSError: [Errno 8] Exec format error`. Linux wheels are now tagged `manylinux_2_17_<arch>.musllinux_1_2_<arch>` (instead of `musllinux_1_2_<arch>` only), so pip accepts them on both glibc-2.17+ and musl distros. The `pypi/hatch_build.py` hook now hard-fails when `KINGFISHER_PYPI_WHEEL_TAG` is unset, and the publish workflow refuses to upload any `py3-none-any.whl`, so the v1.92.0-era pure-Python wheel cannot recur.
|
||||
- `--self-update` (alias `--update`) on a scan or other command now **re-execs into the freshly installed binary** so the current invocation completes with the new code and the latest detection rules. Previously the on-disk binary was replaced but the running process kept using the old in-memory version, requiring a second invocation to pick up the changes. On Unix this is a true `exec()` (same PID); on Windows the new binary is spawned and the parent exits with its status code. The explicit `kingfisher self-update` subcommand still updates and exits without re-execing. Self-update now also covers Windows arm64 (the asset was already published; the runtime cfg map gained the missing arm). See `docs/ADVANCED.md` → *Update Checks*.
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ use zip::ZipArchive;
|
|||
|
||||
/// Formats that are basically a ZIP container.
|
||||
pub const ZIP_BASED_FORMATS: &[&str] = &[
|
||||
"zip", "zipx", "jar", "war", "ear", "aar", "apk", "aab", "ipa", "jmod", "jhm", "jnlp",
|
||||
"nupkg", "vsix", "xap", "docx", "xlsx", "pptx", "odt", "ods", "odp", "odg", "odf", "epub",
|
||||
"gadget", "kmz", "widget", "xpi", "sketch", "pages", "key", "numbers", "hwpx",
|
||||
"zip", "zipx", "jar", "war", "ear", "aar", "apk", "aab", "ipa", "jmod", "jhm", "jnlp", "nupkg",
|
||||
"vsix", "xap", "docx", "xlsx", "pptx", "odt", "ods", "odp", "odg", "odf", "epub", "gadget",
|
||||
"kmz", "widget", "xpi", "sketch", "pages", "key", "numbers", "hwpx",
|
||||
];
|
||||
|
||||
/// Break `<name>.<outer>.<inner>` into `(Some(outer), Some(inner))`.
|
||||
|
|
|
|||
11
src/main.rs
11
src/main.rs
|
|
@ -979,11 +979,7 @@ fn build_config_yaml(
|
|||
// round-trip. Pull the raw CLI/env string from `ArgMatches` instead so
|
||||
// the emitted YAML matches what the user actually passed.
|
||||
fn raw_arg_string(matches: &clap::ArgMatches, id: &str) -> Option<String> {
|
||||
matches
|
||||
.get_raw(id)
|
||||
.and_then(|mut v| v.next())
|
||||
.and_then(|s| s.to_str())
|
||||
.map(str::to_owned)
|
||||
matches.get_raw(id).and_then(|mut v| v.next()).and_then(|s| s.to_str()).map(str::to_owned)
|
||||
}
|
||||
if user_set(sub_matches, "github_api_url") {
|
||||
git.github_api_url = raw_arg_string(sub_matches, "github_api_url");
|
||||
|
|
@ -2323,10 +2319,7 @@ alerts:
|
|||
};
|
||||
let yaml = super::build_config_yaml(&scan_args, &global_args, init_matches).unwrap();
|
||||
let cfg = parse_str(&yaml).expect("emitted YAML must round-trip");
|
||||
assert_eq!(
|
||||
cfg.git.github_api_url.as_deref(),
|
||||
Some("https://ghe.corp.example.com/api/v3/"),
|
||||
);
|
||||
assert_eq!(cfg.git.github_api_url.as_deref(), Some("https://ghe.corp.example.com/api/v3/"),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -546,11 +546,7 @@ fn try_extract_git_blob_archive(
|
|||
// correct format (zip-based, gz, tar, ...). decompress_file_to_temp
|
||||
// dispatches on extension, so the extension MUST match the actual
|
||||
// bytes — using the in-tree filename is the right move.
|
||||
let basename = pb
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("blob")
|
||||
.to_string();
|
||||
let basename = pb.file_name().and_then(|s| s.to_str()).unwrap_or("blob").to_string();
|
||||
|
||||
// ── fast path: ZIP-based archives extract entirely in memory ──
|
||||
//
|
||||
|
|
@ -668,10 +664,7 @@ fn try_extract_git_blob_archive(
|
|||
out.push((strip_logical_prefix(logical), bytes));
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(
|
||||
"Failed to read extracted entry {}: {e}",
|
||||
disk_path.display()
|
||||
);
|
||||
debug!("Failed to read extracted entry {}: {e}", disk_path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -747,9 +740,7 @@ impl<'a> rayon::iter::ParallelIterator for GitRepoResultIter<'a> {
|
|||
let repo_path = Arc::clone(&repo_path);
|
||||
let flag = Arc::clone(&flag);
|
||||
|
||||
move |repo: &mut GixRepo,
|
||||
md: GitBlobMetadata|
|
||||
-> Result<Vec<(OriginSet, Blob<'a>)>> {
|
||||
move |repo: &mut GixRepo, md: GitBlobMetadata| -> Result<Vec<(OriginSet, Blob<'a>)>> {
|
||||
if StdInstant::now() > deadline {
|
||||
if flag.swap(true, Ordering::Relaxed) {
|
||||
bail!("__timeout_silenced__");
|
||||
|
|
@ -777,18 +768,17 @@ impl<'a> rayon::iter::ParallelIterator for GitRepoResultIter<'a> {
|
|||
Ok(Some(entries)) => {
|
||||
let mut out = Vec::with_capacity(entries.len());
|
||||
for (entry_logical, entry_bytes) in entries {
|
||||
let origin = OriginSet::try_from_iter(
|
||||
md.first_seen.iter().map(|e| {
|
||||
let origin =
|
||||
OriginSet::try_from_iter(md.first_seen.iter().map(|e| {
|
||||
Origin::from_git_repo_with_first_commit(
|
||||
Arc::clone(&repo_path),
|
||||
Arc::clone(&e.commit_metadata),
|
||||
entry_logical.clone(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.unwrap_or_else(|| {
|
||||
Origin::from_git_repo(Arc::clone(&repo_path)).into()
|
||||
});
|
||||
}))
|
||||
.unwrap_or_else(
|
||||
|| Origin::from_git_repo(Arc::clone(&repo_path)).into(),
|
||||
);
|
||||
out.push((origin, Blob::from_bytes(entry_bytes)));
|
||||
}
|
||||
return Ok(out);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue