@ 261027.7 · fetching

261018.1 · 4caa87cda978f25211499266fcc99e637c582ebc

chore: update swc to v1.16.18

reading declarations

Changes to deps/swc/crates/swc_native_addon/src/integrity.rs. All files

deps/swc/crates/swc_native_addon/src/integrity.rs

new file mode 100644@@ -0,0 +1,160 @@+//! Private carrier metadata, separate from the stable v1 payload format.+//!+//! The build and release verifier establish SHA-512 equality first. Runtime+//! verification uses BLAKE3 over every byte, bound to that complete v1 header.+//! Neither digest authenticates an untrusted carrier or replaces code signing.++use std::io::{Read, Seek};++use sha2::{Digest, Sha512};++use crate::{+    format::{Header, HEADER_LEN},+    Error, ErrorKind, Result,+};++pub const INTEGRITY_MAGIC: &[u8; 8] = b"SWCNB3V1";+pub const INTEGRITY_LEN: usize = 8 + HEADER_LEN + 32;++#[derive(Clone, Debug)]+pub struct RuntimeIntegrity {+    header: [u8; HEADER_LEN],+    digest: [u8; 32],+}++impl RuntimeIntegrity {+    /// Derive runtime metadata only from bytes verified against the SHA-512+    /// payload header. This runs during building, never on a cache hit.+    pub fn from_raw(header: &Header, raw: &mut (impl Read + Seek)) -> Result<Self> {+        header.verify(raw)?;+        raw.rewind()+            .map_err(|e| Error::io(ErrorKind::Integrity, "rewind verified raw addon", e))?;+        let mut hash = blake3::Hasher::new();+        let mut buffer = [0; 64 * 1024];+        loop {+            let len = raw+                .read(&mut buffer)+                .map_err(|e| Error::io(ErrorKind::Integrity, "hash verified raw addon", e))?;+            if len == 0 {+                break;+            }+            hash.update(&buffer[..len]);+        }+        Ok(Self {+            header: header.encode(),+            digest: *hash.finalize().as_bytes(),+        })+    }++    pub fn encode(&self) -> [u8; INTEGRITY_LEN] {+        let mut bytes = [0; INTEGRITY_LEN];+        bytes[..8].copy_from_slice(INTEGRITY_MAGIC);+        bytes[8..8 + HEADER_LEN].copy_from_slice(&self.header);+        bytes[8 + HEADER_LEN..].copy_from_slice(&self.digest);+        bytes+    }++    pub fn parse(bytes: &[u8]) -> Result<Self> {+        if bytes.len() != INTEGRITY_LEN || &bytes[..8] != INTEGRITY_MAGIC {+            return Err(Error::new(+                ErrorKind::Integrity,+                "invalid native runtime integrity metadata",+            ));+        }+        Ok(Self {+            header: bytes[8..8 + HEADER_LEN].try_into().unwrap(),+            digest: bytes[8 + HEADER_LEN..].try_into().unwrap(),+        })+    }++    pub(crate) fn verifier(&self, header: &Header) -> Result<Verifier> {+        if self.header != header.encode() {+            return Err(Error::new(+                ErrorKind::Integrity,+                "runtime integrity metadata does not match payload header",+            ));+        }+        Ok(Verifier::Blake3(Box::default(), self.digest))+    }+}++/// Select a digest once per verification, with no persistent validation cache.+pub(crate) enum Verifier {+    Sha512(Box<Sha512>, [u8; 64]),+    Blake3(Box<blake3::Hasher>, [u8; 32]),+}++impl Verifier {+    pub(crate) fn sha512(header: &Header) -> Self {+        Self::Sha512(Box::default(), header.digest)+    }++    pub(crate) fn buffer_len(&self, _raw_len: u64) -> usize {+        // Enter the worker pool once for ordinary addon sizes. Repeated 1 MiB+        // dispatches stall Rosetta verification on constrained CI hosts. Bound+        // scratch memory even for the largest accepted payloads; the buffer is+        // freed after verification. Small images and SHA-512 keep streaming.+        #[cfg(all(target_os = "macos", target_arch = "x86_64"))]+        if matches!(self, Self::Blake3(..)) && _raw_len >= 1024 * 1024 {+            return _raw_len.min(32 * 1024 * 1024) as usize;+        }+        64 * 1024+    }++    pub(crate) fn update(&mut self, bytes: &[u8]) {+        match self {+            Self::Sha512(hash, _) => hash.update(bytes),+            Self::Blake3(hash, _) => {+                #[cfg(all(target_os = "macos", target_arch = "x86_64"))]+                if bytes.len() >= 128 * 1024 {+                    if let Some(pool) = verification_pool() {+                        pool.install(|| hash.update_rayon(bytes));+                        return;+                    }+                }+                hash.update(bytes);+            }+        }+    }++    pub(crate) fn finish(self) -> Result<()> {+        let algorithm = match self {+            Self::Sha512(hash, expected) => {+                if hash.finalize()[..] == expected {+                    return Ok(());+                }+                "SHA-512"+            }+            Self::Blake3(hash, expected) => {+                if hash.finalize().as_bytes() == &expected {+                    return Ok(());+                }+                "BLAKE3"+            }+        };+        Err(Error::new(+            ErrorKind::Integrity,+            format!("raw addon {algorithm} mismatch"),+        ))+    }+}++/// Bound Rosetta verification work without using the application's global+/// Rayon pool. Only worker threads are reused: every verification still reads+/// and hashes every file byte. Resource-constrained hosts hash sequentially.+#[cfg(all(target_os = "macos", target_arch = "x86_64"))]+fn verification_pool() -> Option<&'static rayon_core::ThreadPool> {+    static POOL: std::sync::OnceLock<Option<rayon_core::ThreadPool>> = std::sync::OnceLock::new();+    POOL.get_or_init(|| {+        let threads = std::thread::available_parallelism().ok()?.get().min(4);+        if threads < 2 {+            return None;+        }+        rayon_core::ThreadPoolBuilder::new()+            .num_threads(threads)+            .thread_name(|index| format!("swc-native-verify-{index}"))+            .build()+            .ok()+    })+    .as_ref()+}