diff --git a/src/boringssl_sys/boringssl.rs b/src/boringssl_sys/boringssl.rs index b4467c77ceeb..db219ecb6167 100644 --- a/src/boringssl_sys/boringssl.rs +++ b/src/boringssl_sys/boringssl.rs @@ -27,9 +27,6 @@ macro_rules! opaque { /// `#define EVP_MAX_MD_SIZE 64` — SHA-512 is the longest digest. pub const EVP_MAX_MD_SIZE: c_int = 64; -/// `#define RIPEMD160_DIGEST_LENGTH 20` -pub const RIPEMD160_DIGEST_LENGTH: c_int = 20; - /// `#define NID_commonName 13` pub(crate) const NID_commonName: c_int = 13; /// `#define NID_subject_alt_name 85` @@ -194,29 +191,6 @@ pub struct SHA256_CTX { pub md_len: c_uint, } -/// `struct sha512_state_st`. -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SHA512_CTX { - pub h: [u64; 8], - pub num: u16, - pub md_len: u16, - pub bytes_so_far_high: u32, - pub bytes_so_far_low: u64, - pub p: [u8; 128], -} - -/// `struct RIPEMD160state_st` (`vendor/boringssl/include/openssl/ripemd.h`). -#[repr(C)] -#[derive(Copy, Clone)] -pub struct RIPEMD160_CTX { - pub h: [u32; 5], - pub Nl: u32, - pub Nh: u32, - pub data: [u8; 64], - pub num: c_uint, -} - // ═══════════════════════════════════════════════════════════════════════════ // X509v3 GENERAL_NAME // ═══════════════════════════════════════════════════════════════════════════ @@ -577,7 +551,6 @@ unsafe extern "C" { // ── EVP digest getters (infallible, return static singletons) ──────── pub safe fn EVP_md4() -> *const EVP_MD; pub safe fn EVP_md5() -> *const EVP_MD; - pub safe fn EVP_md5_sha1() -> *const EVP_MD; pub safe fn EVP_ripemd160() -> *const EVP_MD; pub safe fn EVP_sha1() -> *const EVP_MD; pub safe fn EVP_sha224() -> *const EVP_MD; @@ -653,30 +626,6 @@ unsafe extern "C" { pub fn SHA256_Final(out: *mut u8, sha: *mut SHA256_CTX) -> c_int; pub fn SHA256(data: *const u8, len: usize, out: *mut u8) -> *mut u8; - // ── SHA-384 ────────────────────────────────────────────────────────── - pub fn SHA384_Init(sha: *mut SHA512_CTX) -> c_int; - pub fn SHA384_Update(sha: *mut SHA512_CTX, data: *const c_void, len: usize) -> c_int; - pub fn SHA384_Final(out: *mut u8, sha: *mut SHA512_CTX) -> c_int; - pub fn SHA384(data: *const u8, len: usize, out: *mut u8) -> *mut u8; - - // ── SHA-512 ────────────────────────────────────────────────────────── - pub fn SHA512_Init(sha: *mut SHA512_CTX) -> c_int; - pub fn SHA512_Update(sha: *mut SHA512_CTX, data: *const c_void, len: usize) -> c_int; - pub fn SHA512_Final(out: *mut u8, sha: *mut SHA512_CTX) -> c_int; - pub fn SHA512(data: *const u8, len: usize, out: *mut u8) -> *mut u8; - - // ── SHA-512/256 ────────────────────────────────────────────────────── - pub fn SHA512_256_Init(sha: *mut SHA512_CTX) -> c_int; - pub fn SHA512_256_Update(sha: *mut SHA512_CTX, data: *const c_void, len: usize) -> c_int; - pub fn SHA512_256_Final(out: *mut u8, sha: *mut SHA512_CTX) -> c_int; - pub fn SHA512_256(data: *const u8, len: usize, out: *mut u8) -> *mut u8; - - // ── RIPEMD-160 ─────────────────────────────────────────────────────── - pub fn RIPEMD160_Init(ctx: *mut RIPEMD160_CTX) -> c_int; - pub fn RIPEMD160_Update(ctx: *mut RIPEMD160_CTX, data: *const c_void, len: usize) -> c_int; - pub fn RIPEMD160_Final(out: *mut u8, ctx: *mut RIPEMD160_CTX) -> c_int; - pub fn RIPEMD160(data: *const u8, len: usize, out: *mut u8) -> *mut u8; - // ── SSL ────────────────────────────────────────────────────────────── pub safe fn SSL_library_init() -> c_int; pub safe fn SSL_load_error_strings(); @@ -878,9 +827,7 @@ unsafe extern "C" { pub fn SSL_CTX_free(ctx: *mut SSL_CTX); pub fn SSL_CTX_get_verify_mode(ctx: *const SSL_CTX) -> c_int; pub fn SSL_CTX_set_ex_data(ctx: *mut SSL_CTX, idx: c_int, data: *mut c_void) -> c_int; - pub fn SSL_CTX_get_ex_data(ctx: *const SSL_CTX, idx: c_int) -> *mut c_void; pub fn SSL_CTX_set0_buffer_pool(ctx: *mut SSL_CTX, pool: *mut CRYPTO_BUFFER_POOL); - pub fn SSL_CTX_set_cipher_list(ctx: *mut SSL_CTX, str_: *const c_char) -> c_int; pub fn SSL_CTX_set1_groups_list(ctx: *mut SSL_CTX, groups: *const c_char) -> c_int; /// `enum ssl_compliance_policy_t` (int-sized via BORINGSSL_ENUM_INT). pub fn SSL_CTX_set_compliance_policy(ctx: *mut SSL_CTX, policy: c_int) -> c_int; @@ -991,7 +938,6 @@ unsafe extern "C" { // Thread-local error queue — no pointer args, no preconditions. pub safe fn ERR_clear_error(); pub safe fn ERR_get_error() -> u32; - pub safe fn ERR_peek_error() -> u32; pub safe fn ERR_peek_last_error() -> u32; pub fn ERR_error_string(packed_error: u32, buf: *mut c_char) -> *mut c_char; // `ERR_error_string_n` declared once in the crypto/err block above. @@ -1083,10 +1029,6 @@ opaque!( /// `struct evp_pkey_st` (`typedef ... EVP_PKEY`). EVP_PKEY ); -opaque!( - /// `struct ssl_cipher_st` (`typedef ... SSL_CIPHER`). - SSL_CIPHER -); opaque!( /// `struct ssl_session_st` (`typedef ... SSL_SESSION`). SSL_SESSION @@ -1105,10 +1047,6 @@ unsafe extern "C" { pub fn SSL_CTX_use_PrivateKey(ctx: *mut SSL_CTX, pkey: *mut EVP_PKEY) -> c_int; pub fn SSL_get_verify_result(ssl: *const SSL) -> c_long; - pub fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER; - pub fn SSL_CIPHER_standard_name(cipher: *const SSL_CIPHER) -> *const c_char; - pub fn SSL_CIPHER_get_name(cipher: *const SSL_CIPHER) -> *const c_char; - pub fn SSL_get_version(ssl: *const SSL) -> *const c_char; pub fn PEM_read_bio_X509( bp: *mut BIO, @@ -1126,7 +1064,6 @@ unsafe extern "C" { pub fn X509_verify_cert_error_string(err: c_long) -> *const c_char; - pub fn X509_STORE_free(store: *mut X509_STORE); pub fn X509_STORE_add_cert(store: *mut X509_STORE, x509: *mut X509) -> c_int; pub fn X509_STORE_add_crl(store: *mut X509_STORE, crl: *mut X509_CRL) -> c_int; pub fn X509_STORE_set_flags(store: *mut X509_STORE, flags: c_ulong) -> c_int; @@ -1144,12 +1081,6 @@ unsafe extern "C" { /// Returns a BORROWED reference to the local certificate, or null. pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; - pub fn i2d_SSL_SESSION(session: *mut SSL_SESSION, pp: *mut *mut u8) -> c_int; - pub fn d2i_SSL_SESSION( - a: *mut *mut SSL_SESSION, - pp: *mut *const u8, - length: c_long, - ) -> *mut SSL_SESSION; pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; pub fn SSL_SESSION_free(session: *mut SSL_SESSION); } diff --git a/src/http/InternalState.rs b/src/http/InternalState.rs index 7b287e4f7719..9d4f4e8e74d8 100644 --- a/src/http/InternalState.rs +++ b/src/http/InternalState.rs @@ -104,13 +104,6 @@ impl InternalStateFlags { } } -impl Default for InternalStateFlags { - /// `allow_keepalive` defaults to true. - fn default() -> Self { - Self::new() - } -} - impl Default for InternalState<'_> { fn default() -> Self { Self { diff --git a/src/http/lib.rs b/src/http/lib.rs index ab48559ff439..d4d5308d553f 100644 --- a/src/http/lib.rs +++ b/src/http/lib.rs @@ -124,16 +124,6 @@ pub struct HTTPResponseMetadata { pub response: bun_picohttp::Response<'static>, } -impl Default for HTTPResponseMetadata { - fn default() -> Self { - Self { - url: bun_ptr::RawSlice::EMPTY, - owned_buf: Box::default(), - response: bun_picohttp::Response::default(), - } - } -} - impl HTTPResponseMetadata { /// Accessors tied to `&self`: `response` is typed `'static` but its slices /// borrow the sibling `owned_buf` / header slice that `Drop` frees, so @@ -157,10 +147,7 @@ impl HTTPResponseMetadata { } impl Drop for HTTPResponseMetadata { - // `owned_buf` is freed by - // `Box`'s own Drop; `response.headers.list` was `Box::leak`'d in - // `clone_metadata` and must be reclaimed here. `Default` / zero-header - // responses have an empty static slice, guarded by the len check. + // `response.headers.list` is `Box::leak`'d by `clone_metadata`; reclaim it here. fn drop(&mut self) { let list = self.response.headers.list; if !list.is_empty() { diff --git a/src/install/PackageInstaller.rs b/src/install/PackageInstaller.rs index 6c96867f593b..ac2ce7fe6e9c 100644 --- a/src/install/PackageInstaller.rs +++ b/src/install/PackageInstaller.rs @@ -18,13 +18,13 @@ use crate::bun_progress::{Node as ProgressNode, Progress}; use crate::lifecycle_script_runner::LifecycleScriptSubprocess; // `Lockfile` here is the in-crate `crate::lockfile::Lockfile` (the // struct `PackageManager.lockfile` actually carries). `lockfile_real` is still -// imported for `tree::Id` / `Tree` / `DependencySlice` / `package::*`, all of +// imported for `tree::Id` / `Tree` / `package::*`, all of // which are the same types re-exported through `crate::lockfile`. use crate::lockfile::Lockfile; use crate::lockfile_real::package::{ self as Package, PackageColumns, scripts::Scripts as PackageScripts, }; -use crate::lockfile_real::{self as lockfile, DependencySlice, Tree}; +use crate::lockfile_real::{self as lockfile, Tree}; use crate::network_task::ForTarballError; use crate::package_install::{self, PackageInstall}; use crate::package_manager::{self, Options, PackageManager}; @@ -84,7 +84,6 @@ pub struct PackageInstaller<'a> { // so it is also `RawSlice` here. pub(crate) metas: bun_ptr::RawSlice, pub(crate) names: bun_ptr::RawSlice, - pub(crate) pkg_dependencies: bun_ptr::RawSlice, pub(crate) pkg_name_hashes: bun_ptr::RawSlice, pub(crate) bins: bun_ptr::RawSlice, pub(crate) resolutions: bun_ptr::RawSlice, @@ -361,48 +360,6 @@ fn abs_node_modules_path( abs } -enum LazyPackageDestinationDir<'a> { - /// Non-owning view of a directory handle the caller owns. - #[allow(dead_code)] - Dir(Fd), - NodeModulesPath { - #[allow(dead_code)] - node_modules: &'a NodeModulesFolder, - /// Non-owning view; the owning `Dir` lives on `PackageInstaller`. - root_node_modules_dir: Fd, - }, - Owned(Dir), - Closed, -} - -impl<'a> LazyPackageDestinationDir<'a> { - #[allow(dead_code)] - pub(crate) fn get_dir(&mut self) -> crate::Result { - match self { - LazyPackageDestinationDir::Dir(fd) => Ok(*fd), - LazyPackageDestinationDir::Owned(dir) => Ok(dir.fd()), - LazyPackageDestinationDir::NodeModulesPath { - node_modules, - root_node_modules_dir, - } => { - let dir = node_modules.open_dir(Dir::borrow(root_node_modules_dir))?; - let fd = dir.fd(); - *self = LazyPackageDestinationDir::Owned(dir); - Ok(fd) - } - LazyPackageDestinationDir::Closed => { - panic!( - "LazyPackageDestinationDir is closed! This should never happen. Why did this happen?! It's not your fault. Its our fault. We're sorry." - ) - } - } - } - - fn close(&mut self) { - *self = LazyPackageDestinationDir::Closed; - } -} - /// A dependency alias becomes the install destination inside `node_modules` /// (the existing entry is renamed aside, deleted, and re-created). Reject /// anything that could escape `node_modules`: empty names, `.`/`..` @@ -1082,7 +1039,6 @@ impl<'a> PackageInstaller<'a> { self.pkg_name_hashes = bun_ptr::RawSlice::new(packages.items_name_hash()); self.bins = bun_ptr::RawSlice::new(packages.items_bin()); self.resolutions = bun_ptr::RawSlice::new(packages.items_resolution()); - self.pkg_dependencies = bun_ptr::RawSlice::new(packages.items_dependencies()); // fixes an assertion failure where a transitive dependency is a git dependency newly added to the lockfile after the list of dependencies has been resized // this assertion failure would also only happen after the lockfile has been written to disk and the summary is being printed. @@ -1818,9 +1774,6 @@ impl<'a> PackageInstaller<'a> { } }; - #[cfg(not(windows))] - let mut lazy_package_dir = LazyPackageDestinationDir::Dir(destination_dir.fd()); - let install_result: package_install::InstallResult = match resolution.tag { resolution::Tag::Symlink | resolution::Tag::Workspace => { installer.install_from_link(self.skip_delete, &destination_dir) @@ -2127,24 +2080,7 @@ impl<'a> PackageInstaller<'a> { if !NODE_MODULES_IS_OK.load(Ordering::Relaxed) { #[cfg(not(windows))] { - let dir = match lazy_package_dir.get_dir() { - Ok(d) => d, - Err(err) => { - Output::err( - "EACCES", - "Permission denied while installing {}", - (bstr::BStr::new( - self.names[package_id as usize].slice( - self.lockfile().buffers.string_bytes.as_slice(), - ), - ),), - ); - if cfg!(debug_assertions) { - Output::err(err, "Failed to stat node_modules", ()); - } - Global::exit(1); - } - }; + let dir = destination_dir.fd(); let stat = match bun_sys::fstat(dir) { Ok(s) => s, Err(err) => { @@ -2248,19 +2184,6 @@ impl<'a> PackageInstaller<'a> { .unwrap_or_oom(); } - // reshaped for borrowck — `LazyPackageDestinationDir` borrows - // `&self.node_modules`, but this else-branch never reads `destination_dir` - // (it only `close()`s it at the end, which is a no-op for `NodeModulesPath`). - // Detach via raw ptr so subsequent `&mut self` calls type-check. - // BACKREF — `self.node_modules` is not moved/dropped in this branch. - let mut destination_dir = LazyPackageDestinationDir::NodeModulesPath { - node_modules: node_modules_ref.get(), - root_node_modules_dir: self.root_node_modules_folder.fd(), - }; - - // `defer { destination_dir.close(); }` + `defer increment_tree_install_count`. - // No early returns after this point, so manual calls at end are equivalent. - let dep = &self.lockfile().buffers.dependencies.as_slice()[dependency_id as usize]; let dep_behavior = dep.behavior; let truncated_dep_name_hash: TruncatedPackageNameHash = @@ -2370,13 +2293,6 @@ impl<'a> PackageInstaller<'a> { } } - // `destination_dir` is `LazyPackageDestinationDir::NodeModulesPath` - // holding `&self.node_modules`. `increment_tree_install_count` takes - // `&mut self` and (via `link_tree_bins`) reads `self.node_modules.path`, - // which would alias the borrow held by `destination_dir`. Close it first - // — `destination_dir` is never read in this else-branch (`get_dir()` is - // only used in the `needs_install` branch's EACCES handler). - destination_dir.close(); self.increment_tree_install_count( !IS_PENDING_PACKAGE_INSTALL, self.current_tree_id, diff --git a/src/install/PackageManager/PackageManagerResolution.rs b/src/install/PackageManager/PackageManagerResolution.rs index 962859afb17f..eca00b0e3254 100644 --- a/src/install/PackageManager/PackageManagerResolution.rs +++ b/src/install/PackageManager/PackageManagerResolution.rs @@ -112,8 +112,7 @@ impl PackageManager { Err( crate::Error::Sys(bun_errno::SystemErrno::ENOENT) | crate::Error::Sys(bun_errno::SystemErrno::ENOTDIR) - | crate::Error::Sys(bun_errno::SystemErrno::EACCES) - | crate::Error::DeviceBusy, + | crate::Error::Sys(bun_errno::SystemErrno::EACCES), ) => { return Ok(list); } diff --git a/src/install/dependency.rs b/src/install/dependency.rs index 2f5b38f9b895..693333f1c49b 100644 --- a/src/install/dependency.rs +++ b/src/install/dependency.rs @@ -72,8 +72,6 @@ pub trait DependencyExt { log: impl Into>, package_manager: impl Into>, ) -> Option; - fn is_less_than(string_buf: &[u8], lhs: &Dependency, rhs: &Dependency) -> bool; - fn cmp(string_buf: &[u8], lhs: &Dependency, rhs: &Dependency) -> Ordering; fn count_with_different_buffers( &self, name_buf: &[u8], @@ -95,7 +93,6 @@ pub trait DependencyExt { builder: &mut SB, ) -> Result; fn realname(&self) -> String; - fn is_aliased(&self, buf: &[u8]) -> bool; fn eql(&self, b: &Dependency, lhs_buf: &[u8], rhs_buf: &[u8]) -> bool; fn is_remote_tarball(dep: &[u8]) -> bool; fn parse<'a, 'b>( @@ -159,32 +156,6 @@ impl DependencyExt for Dependency { ) } - /// Sorting order for dependencies is: - /// 1. [ `workspaces`, `devDependencies`, `optionalDependencies`, `dependencies`, `peerDependencies` ] - /// 2. name ASC - /// "name" must be ASC so that later, when we rebuild the lockfile - /// we insert it back in reverse order without an extra sorting pass - fn is_less_than(string_buf: &[u8], lhs: &Dependency, rhs: &Dependency) -> bool { - let behavior = lhs.behavior.cmp(rhs.behavior); - if behavior != Ordering::Equal { - return behavior == Ordering::Less; - } - - let lhs_name = lhs.name.slice(string_buf); - let rhs_name = rhs.name.slice(string_buf); - strings::cmp_strings_asc((), lhs_name, rhs_name) - } - - /// Total-order comparator for `slice::sort_by`. Same key as - /// `is_less_than`: behavior group, then name ASC. - fn cmp(string_buf: &[u8], lhs: &Dependency, rhs: &Dependency) -> Ordering { - let behavior = lhs.behavior.cmp(rhs.behavior); - if behavior != Ordering::Equal { - return behavior; - } - lhs.name.slice(string_buf).cmp(rhs.name.slice(string_buf)) - } - fn count_with_different_buffers( &self, name_buf: &[u8], @@ -257,18 +228,6 @@ impl DependencyExt for Dependency { } } - #[inline] - fn is_aliased(&self, buf: &[u8]) -> bool { - match self.version.tag { - Tag::Npm => !self.version.npm().name.eql(self.name, buf, buf), - Tag::DistTag => !self.version.dist_tag().name.eql(self.name, buf, buf), - Tag::Git => !self.version.git().package_name.eql(self.name, buf, buf), - Tag::Github => !self.version.github().package_name.eql(self.name, buf, buf), - Tag::Tarball => !self.version.tarball().package_name.eql(self.name, buf, buf), - _ => false, - } - } - fn eql(&self, b: &Dependency, lhs_buf: &[u8], rhs_buf: &[u8]) -> bool { self.name_hash == b.name_hash && self.name.len() == b.name.len() @@ -591,12 +550,6 @@ pub fn without_build_tag(version: &[u8]) -> &[u8] { pub(crate) type VersionExternal = [u8; 9]; pub trait VersionExt { - fn zeroed() -> Version; - fn clone_in( - &self, - buf: &[u8], - builder: &mut SB, - ) -> Result; fn is_less_than_with_tag(string_buf: &[u8], lhs: &Version, rhs: &Version) -> bool; fn to_version( alias: String, @@ -609,24 +562,6 @@ pub trait VersionExt { } impl VersionExt for Version { - #[inline] - fn zeroed() -> Version { - Version::default() - } - - /// Named `clone_in` so it doesn't shadow `std::clone::Clone::clone`. - fn clone_in( - &self, - buf: &[u8], - builder: &mut SB, - ) -> Result { - Ok(Version { - tag: self.tag, - literal: builder.append_string(self.literal.slice(buf)), - value: self.value.clone_in(self.tag, buf, builder)?, - }) - } - fn is_less_than_with_tag(string_buf: &[u8], lhs: &Version, rhs: &Version) -> bool { let tag_order = lhs.tag.cmp(rhs.tag); if tag_order != Ordering::Equal { @@ -1096,40 +1031,6 @@ impl TagExt for Tag { } } -// ────────────────────────────────────────────────────────────────────────── -// Version payload types -// ────────────────────────────────────────────────────────────────────────── - -pub trait ValueExt { - fn clone_in( - &self, - _tag: Tag, - _buf: &[u8], - _builder: &mut SB, - ) -> Result; -} - -impl ValueExt for Value { - fn clone_in( - &self, - tag: Tag, - _buf: &[u8], - _builder: &mut SB, - ) -> Result { - Ok(match tag { - Tag::Npm => { - // SAFETY: `tag == Npm` selects the `npm` union arm. - let npm = unsafe { (*self.npm).clone() }; - Value { - npm: ManuallyDrop::new(npm), - } - } - // SAFETY: every other arm is `Copy` (no heap), so a bitwise read is a true clone. - _ => unsafe { core::ptr::read(self) }, - }) - } -} - // ────────────────────────────────────────────────────────────────────────── // Free functions: parse // ────────────────────────────────────────────────────────────────────────── diff --git a/src/install/error.rs b/src/install/error.rs index 6219d1ed0dc8..1b2e2e464587 100644 --- a/src/install/error.rs +++ b/src/install/error.rs @@ -14,8 +14,6 @@ pub enum Error { SystemFdQuotaExceeded, #[error("SystemResources")] SystemResources, - #[error("DeviceBusy")] - DeviceBusy, #[error("TarballHTTP400")] TarballHTTP400, #[error("TarballHTTP401")] @@ -156,8 +154,6 @@ pub enum Error { DebugTextLockfileRoundTrip, #[error("NoPackage")] NoPackage, - #[error("BrokenPipe")] - BrokenPipe, #[error("WriteFailed")] WriteFailed, #[error("InvalidCharacter")] @@ -180,8 +176,6 @@ pub enum Error { MissingPackageName, #[error("GlobError")] GlobError, - #[error("Invalid")] - Invalid, #[error("Lockfile validation failed: list is impossibly long")] LockfileValidationFailedListIsImpossiblyLong, #[error("Lockfile validation failed: alignment mismatch")] @@ -254,7 +248,6 @@ impl Error { Self::SymLinkLoop => "SymLinkLoop", Self::SystemFdQuotaExceeded => "SystemFdQuotaExceeded", Self::SystemResources => "SystemResources", - Self::DeviceBusy => "DeviceBusy", Self::TarballHTTP400 => "TarballHTTP400", Self::TarballHTTP401 => "TarballHTTP401", Self::TarballHTTP402 => "TarballHTTP402", @@ -329,7 +322,6 @@ impl Error { Self::RepositoryNotFound => "RepositoryNotFound", Self::DebugTextLockfileRoundTrip => "DebugTextLockfileRoundTrip", Self::NoPackage => "NoPackage", - Self::BrokenPipe => "BrokenPipe", Self::WriteFailed => "WriteFailed", Self::InvalidCharacter => "InvalidCharacter", Self::InvalidLockfile => "InvalidLockfile", @@ -343,7 +335,6 @@ impl Error { Self::LockfileIsMissingResolutionData => "Lockfile is missing resolution data", Self::MissingPackageName => "MissingPackageName", Self::GlobError => "GlobError", - Self::Invalid => "Invalid", Self::LockfileValidationFailedListIsImpossiblyLong => { "Lockfile validation failed: list is impossibly long" } diff --git a/src/install/hoisted_install.rs b/src/install/hoisted_install.rs index 81dc1dc5ee53..0feed3052424 100644 --- a/src/install/hoisted_install.rs +++ b/src/install/hoisted_install.rs @@ -356,7 +356,6 @@ pub(crate) fn install_hoisted_packages( let names = bun_ptr::RawSlice::new(parts.items_name()); let pkg_name_hashes = bun_ptr::RawSlice::new(parts.items_name_hash()); let resolutions = bun_ptr::RawSlice::new(parts.items_resolution()); - let pkg_dependencies = bun_ptr::RawSlice::new(parts.items_dependencies()); // Hoist the by-value reads out of the struct literal so they // finish before the long-lived `&mut *mgr_ptr` borrow for @@ -378,7 +377,6 @@ pub(crate) fn install_hoisted_packages( names, pkg_name_hashes, resolutions, - pkg_dependencies, lockfile: lockfile_ptr, root_node_modules_folder: node_modules_folder, node: &mut install_node, diff --git a/src/install/lib.rs b/src/install/lib.rs index aaa1d4ba102f..93cfeb4d34e6 100644 --- a/src/install/lib.rs +++ b/src/install/lib.rs @@ -286,7 +286,7 @@ pub use external::VersionSlice; pub use external_slice as external; pub use dependency::Behavior; -pub use dependency::{Dependency, DependencyExt, TagExt, ValueExt, VersionExt}; +pub use dependency::{Dependency, DependencyExt, TagExt, VersionExt}; pub use integrity::Integrity; pub use bin::Bin; diff --git a/src/install/lockfile.rs b/src/install/lockfile.rs index 2dbffb561693..479ccd125c38 100644 --- a/src/install/lockfile.rs +++ b/src/install/lockfile.rs @@ -1653,7 +1653,7 @@ impl<'a> Printer<'a> { match Self::print_with_lockfile(&lockfile, format, writer) { Ok(()) => {} Err(crate::Error::Alloc(bun_alloc::AllocError)) => bun_core::out_of_memory(), - Err(crate::Error::BrokenPipe) | Err(crate::Error::WriteFailed) => return Ok(()), + Err(crate::Error::WriteFailed) => return Ok(()), Err(e) => return Err(e), } Output::flush(); diff --git a/src/install/repository.rs b/src/install/repository.rs index 58978edbb073..d48f93518218 100644 --- a/src/install/repository.rs +++ b/src/install/repository.rs @@ -405,7 +405,6 @@ fn exec(env: &bun_dotenv::Map, argv: &[&[u8]]) -> Result, Error> { let term = match result.term { bun_spawn::Term::Exited(code) => format!("exit code {code}"), bun_spawn::Term::Signal(sig) => format!("signal {sig}"), - bun_spawn::Term::Stopped(sig) => format!("stopped (signal {sig})"), bun_spawn::Term::Unknown(_) => "unknown status".to_string(), }; Output::err_generic("{} failed with {}", (BStr::new(argv[0]), term.as_str())); diff --git a/src/io/lib.rs b/src/io/lib.rs index 62e083df2b0c..c9954cd44b2f 100644 --- a/src/io/lib.rs +++ b/src/io/lib.rs @@ -1322,16 +1322,6 @@ macro_rules! intrusive_uv_fs { }; } -impl Default for Request { - fn default() -> Self { - Self { - next: bun_threading::Link::new(), - callback: |_| unreachable!(), - scheduled: false, - } - } -} - // Intrusive MPSC queue keyed on the `next` field. // // `next` is stored as `AtomicPtr`; the non-atomic accessor diff --git a/src/io/pipe_read_scratch.rs b/src/io/pipe_read_scratch.rs index 9fd3667e459f..35336873a896 100644 --- a/src/io/pipe_read_scratch.rs +++ b/src/io/pipe_read_scratch.rs @@ -27,12 +27,6 @@ impl PipeReadScratch { } } -impl Default for PipeReadScratch { - fn default() -> Self { - Self::new() - } -} - /// Exclusive claim on the scratch; released on drop. pub struct PipeReadScratchGuard<'a>(&'a PipeReadScratch); diff --git a/src/jsc/TextCodec.rs b/src/jsc/TextCodec.rs index e8e29773f243..ca2ecfc82bf2 100644 --- a/src/jsc/TextCodec.rs +++ b/src/jsc/TextCodec.rs @@ -17,9 +17,6 @@ unsafe extern "C" { out_saw_error: *mut bool, ) -> BunString; fn Bun__deleteTextCodec(codec: *mut TextCodec); - // safe: `TextCodec` is an `opaque_ffi!` ZST handle; `&mut` is ABI-identical - // to a non-null `*mut` and C++ mutating codec state is interior to the cell. - safe fn Bun__stripBOMFromTextCodec(codec: &mut TextCodec); } bun_opaque::opaque_ffi! { @@ -65,9 +62,4 @@ impl TextCodec { DecodeResult { result, saw_error } } - - pub fn strip_bom(&mut self) { - mark_binding!(); - Bun__stripBOMFromTextCodec(self) - } } diff --git a/src/jsc/bindings/EncodingTables.h b/src/jsc/bindings/EncodingTables.h index ca3d1d7e7acf..d1996cc26ef4 100644 --- a/src/jsc/bindings/EncodingTables.h +++ b/src/jsc/bindings/EncodingTables.h @@ -44,12 +44,9 @@ void checkEncodingTableInvariants(); // Functions for using sorted arrays of pairs as a map. // FIXME: Consider moving these functions to StdLibExtras.h for uses other than encoding tables. -template void sortByFirst(CollectionType&); -template void stableSortByFirst(CollectionType&); template bool isSortedByFirst(const CollectionType&); template bool sortedFirstsAreUnique(const CollectionType&); template static auto findFirstInSortedPairs(const CollectionType& sortedPairsCollection, const KeyType&) -> std::optionalsecond)>; -template static auto findInSortedPairs(const CollectionType& sortedPairsCollection, const KeyType&) -> std::span>; #if !ASSERT_ENABLED inline void checkEncodingTableInvariants() {} @@ -73,13 +70,6 @@ struct EqualFirst { } }; -struct CompareSecond { - template bool operator()(const TypeA& a, const TypeB& b) - { - return a.second < b.second; - } -}; - template struct FirstAdapter { const T& first; }; @@ -88,24 +78,6 @@ template FirstAdapter makeFirstAdapter(const T& value) return { value }; } -template struct SecondAdapter { - const T& second; -}; -template SecondAdapter makeSecondAdapter(const T& value) -{ - return { value }; -} - -template void sortByFirst(CollectionType& collection) -{ - std::sort(std::begin(collection), std::end(collection), CompareFirst {}); -} - -template void stableSortByFirst(CollectionType& collection) -{ - std::stable_sort(std::begin(collection), std::end(collection), CompareFirst {}); -} - template bool isSortedByFirst(const CollectionType& collection) { return std::is_sorted(std::begin(collection), std::end(collection), CompareFirst {}); @@ -127,15 +99,6 @@ template static auto findFirstInSorte return std::nullopt; return iterator->second; } - -template static auto findInSortedPairs(const CollectionType& collection, const KeyType& key) -> std::span> -{ - if constexpr (std::is_integral_v) { - if (key != decltype(std::begin(collection)->first)(key)) - return {}; - } - return std::ranges::equal_range(collection, makeFirstAdapter(key), CompareFirst {}); -} #pragma clang diagnostic pop } diff --git a/src/jsc/bindings/ErrorCode.cpp b/src/jsc/bindings/ErrorCode.cpp index a0ec451de173..fb78105b08fb 100644 --- a/src/jsc/bindings/ErrorCode.cpp +++ b/src/jsc/bindings/ErrorCode.cpp @@ -1478,20 +1478,6 @@ JSC::EncodedJSValue CRYPTO_SIGN_KEY_REQUIRED(JSC::ThrowScope& throwScope, JSC::J return {}; } -JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSValue received, WTF::ASCIILiteral expected) -{ - WTF::StringBuilder builder; - builder.append("Invalid key object type "_s); - JSValueToStringSafe(globalObject, builder, received); - RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); - - builder.append(". Expected "_s); - builder.append(expected); - throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, builder.toString())); - throwScope.release(); - return {}; -} - JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, CryptoKeyType receivedType, ASCIILiteral expected) { WTF::StringBuilder builder; diff --git a/src/jsc/bindings/ErrorCode.h b/src/jsc/bindings/ErrorCode.h index 61767e95da78..e5d201ed5f96 100644 --- a/src/jsc/bindings/ErrorCode.h +++ b/src/jsc/bindings/ErrorCode.h @@ -127,7 +127,6 @@ JSC::EncodedJSValue CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(JSC::ThrowScope&, JSC::JSGlo JSC::EncodedJSValue CRYPTO_INVALID_JWK(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject); JSC::EncodedJSValue CRYPTO_INVALID_JWK(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ASCIILiteral message); JSC::EncodedJSValue CRYPTO_SIGN_KEY_REQUIRED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject); -JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSValue received, WTF::ASCIILiteral expected); JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, CryptoKeyType receivedType, WTF::ASCIILiteral expected); JSC::EncodedJSValue CRYPTO_INCOMPATIBLE_KEY_OPTIONS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::StringView& receivedKeyEncoding, const WTF::String& expectedOperation); JSC::EncodedJSValue CRYPTO_INCOMPATIBLE_KEY_OPTIONS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject); diff --git a/src/jsc/bindings/TextCodec.cpp b/src/jsc/bindings/TextCodec.cpp index 0ee4cc6247cc..3c6be34207bb 100644 --- a/src/jsc/bindings/TextCodec.cpp +++ b/src/jsc/bindings/TextCodec.cpp @@ -28,44 +28,10 @@ // config.h removed - not needed in Bun #include "TextCodec.h" -#include #include -#include -#include - -#include -#include namespace PAL { WTF_MAKE_TZONE_ALLOCATED_IMPL(TextCodec); -std::span TextCodec::getUnencodableReplacement(char32_t codePoint, UnencodableHandling handling, UnencodableReplacementArray& replacement) -{ - ASSERT(!(codePoint > UCHAR_MAX_VALUE)); - - // The Encoding Standard doesn't have surrogate code points in the input, but that would require - // scanning and potentially manipulating inputs ahead of time. Instead handle them at the last - // possible point. - if (U_IS_SURROGATE(codePoint)) - codePoint = replacementCharacter; - - switch (handling) { - case UnencodableHandling::Entities: { - int count = SAFE_SPRINTF(std::span { replacement }, "&#%u;", static_cast(codePoint)); - ASSERT(count >= 0); - return std::span { replacement }.first(std::max(0, count)); - } - case UnencodableHandling::URLEncodedEntities: { - int count = SAFE_SPRINTF(std::span { replacement }, "%%26%%23%u%%3B", static_cast(codePoint)); - ASSERT(count >= 0); - return std::span { replacement }.first(std::max(0, count)); - } - } - - ASSERT_NOT_REACHED(); - replacement[0] = '\0'; - return std::span { replacement }.first(0); -} - } // namespace PAL diff --git a/src/jsc/bindings/TextCodec.h b/src/jsc/bindings/TextCodec.h index 3c153397e1ae..be65ebcc2b29 100644 --- a/src/jsc/bindings/TextCodec.h +++ b/src/jsc/bindings/TextCodec.h @@ -26,11 +26,8 @@ #pragma once -#include "UnencodableHandling.h" -#include #include #include -#include #include #include #include @@ -39,8 +36,6 @@ namespace PAL { class TextEncoding; -using UnencodableReplacementArray = std::array; - class TextCodec { WTF_MAKE_TZONE_ALLOCATED(TextCodec); WTF_MAKE_NONCOPYABLE(TextCodec); @@ -49,19 +44,9 @@ class TextCodec { TextCodec() = default; virtual ~TextCodec() = default; - virtual void stripByteOrderMark() {} virtual String decode(std::span data, bool flush, bool stopOnError, bool& sawError) = 0; - - virtual Vector encode(StringView, UnencodableHandling) const = 0; - - // Fills a null-terminated string representation of the given - // unencodable character into the given replacement buffer. - // The length of the string (not including the null) will be returned. - static std::span getUnencodableReplacement(char32_t, UnencodableHandling, UnencodableReplacementArray& replacement LIFETIME_BOUND); }; -Function&)> unencodableHandler(UnencodableHandling); - using EncodingNameRegistrar = void (*)(ASCIILiteral alias, ASCIILiteral name); using NewTextCodecFunction = Function()>; diff --git a/src/jsc/bindings/TextCodecCJK.cpp b/src/jsc/bindings/TextCodecCJK.cpp index 9af99cc41cc4..577737436958 100644 --- a/src/jsc/bindings/TextCodecCJK.cpp +++ b/src/jsc/bindings/TextCodecCJK.cpp @@ -29,10 +29,8 @@ #include "TextCodecCJK.h" #include "EncodingTables.h" -#include #include #include -#include #include #include #include @@ -157,22 +155,6 @@ void TextCodecCJK::registerCodecs(TextCodecRegistrar registrar) }); } -using JIS0208EncodeIndex = std::array, sizeof(jis0208()) / sizeof(jis0208()[0])>; -static const JIS0208EncodeIndex& jis0208EncodeIndex() -{ - // Allocate this at runtime because building it at compile time would make the binary much larger and this is often not used. - static JIS0208EncodeIndex* table; - static std::once_flag once; - std::call_once(once, [&] { - table = new JIS0208EncodeIndex; - auto& index = jis0208(); - for (size_t i = 0; i < index.size(); i++) - (*table)[i] = { index[i].second, index[i].first }; - stableSortByFirst(*table); - }); - return *table; -} - String TextCodecCJK::decodeCommon(std::span bytes, bool flush, bool stopOnError, bool& sawError, NOESCAPE const Function& byteParser) { StringBuilder result; @@ -271,46 +253,6 @@ String TextCodecCJK::eucJPDecode(std::span bytes, bool flush, boo return result; } -// https://encoding.spec.whatwg.org/#euc-jp-encoder -static Vector eucJPEncode(StringView string, Function&)>&& unencodableHandler) -{ - Vector result; - result.reserveInitialCapacity(string.length()); - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) { - auto codePoint = *iterator; - if (isASCII(codePoint)) { - result.append(codePoint); - continue; - } - if (codePoint == 0x00A5) { - result.append(0x5C); - continue; - } - if (codePoint == 0x203E) { - result.append(0x7E); - continue; - } - if (codePoint >= 0xFF61 && codePoint <= 0xFF9F) { - result.append(0x8E); - result.append(codePoint - 0xFF61 + 0xA1); - continue; - } - if (codePoint == 0x2212) - codePoint = 0xFF0D; - - auto pointer = findFirstInSortedPairs(jis0208EncodeIndex(), codePoint); - if (!pointer) { - unencodableHandler(codePoint, result); - continue; - } - result.append(*pointer / 94 + 0xA1); - result.append(*pointer % 94 + 0xA1); - } - return result; -} - // https://encoding.spec.whatwg.org/#iso-2022-jp-decoder String TextCodecCJK::iso2022JPDecode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { @@ -514,109 +456,6 @@ String TextCodecCJK::iso2022JPDecode(std::span bytes, bool flush, return result.toString(); } -// https://encoding.spec.whatwg.org/#iso-2022-jp-encoder -static Vector iso2022JPEncode(StringView string, Function&)>&& unencodableHandler) -{ - enum class State : uint8_t { ASCII, - Roman, - Jis0208 }; - State state { State::ASCII }; - - Vector result; - result.reserveInitialCapacity(string.length()); - - auto changeStateToASCII = [&] { - state = State::ASCII; - result.append(0x1B); - result.append(0x28); - result.append(0x42); - }; - - auto statefulUnencodableHandler = [&](char32_t codePoint, Vector& result) { - if (state == State::Jis0208) - changeStateToASCII(); - unencodableHandler(codePoint, result); - }; - - Function parseCodePoint; - parseCodePoint = [&](char32_t codePoint) { - if ((state == State::ASCII || state == State::Roman) && (codePoint == 0x000E || codePoint == 0x000F || codePoint == 0x001B)) { - statefulUnencodableHandler(replacementCharacter, result); - return; - } - if (state == State::ASCII && isASCII(codePoint)) { - result.append(codePoint); - return; - } - if (state == State::Roman) { - if (isASCII(codePoint) && codePoint != 0x005C && codePoint != 0x007E) { - result.append(codePoint); - return; - } - if (codePoint == 0x00A5) { - result.append(0x5C); - return; - } - if (codePoint == 0x203E) { - result.append(0x7E); - return; - } - } - if (isASCII(codePoint) && state != State::ASCII) { - if (state != State::ASCII) - changeStateToASCII(); - parseCodePoint(codePoint); - return; - } - if ((codePoint == 0x00A5 || codePoint == 0x203E) && state != State::Roman) { - state = State::Roman; - result.append(0x1B); - result.append(0x28); - result.append(0x4A); - parseCodePoint(codePoint); - return; - } - if (codePoint == 0x2212) - codePoint = 0xFF0D; - if (codePoint >= 0xFF61 && codePoint <= 0xFF9F) { - // From https://encoding.spec.whatwg.org/index-iso-2022-jp-katakana.txt - static constexpr std::array iso2022JPKatakana { - 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1, 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, 0x30FC, - 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD, 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD, 0x30BF, - 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE, 0x30DF, - 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C - }; - static_assert(std::size(iso2022JPKatakana) == 0xFF9F - 0xFF61 + 1); - codePoint = iso2022JPKatakana[codePoint - 0xFF61]; - } - - auto pointer = findFirstInSortedPairs(jis0208EncodeIndex(), codePoint); - if (!pointer) { - statefulUnencodableHandler(codePoint, result); - return; - } - if (state != State::Jis0208) { - state = State::Jis0208; - result.append(0x1B); - result.append(0x24); - result.append(0x42); - parseCodePoint(codePoint); - return; - } - result.append(*pointer / 94 + 0x21); - result.append(*pointer % 94 + 0x21); - }; - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) - parseCodePoint(*iterator); - - if (state != State::ASCII) - changeStateToASCII(); - - return result; -} - // https://encoding.spec.whatwg.org/#shift_jis-decoder String TextCodecCJK::shiftJISDecode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { @@ -655,99 +494,6 @@ String TextCodecCJK::shiftJISDecode(std::span bytes, bool flush, }); } -// https://encoding.spec.whatwg.org/#shift_jis-encoder -static Vector shiftJISEncode(StringView string, Function&)>&& unencodableHandler) -{ - Vector result; - result.reserveInitialCapacity(string.length()); - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) { - auto codePoint = *iterator; - if (isASCII(codePoint) || codePoint == 0x0080) { - result.append(codePoint); - continue; - } - if (codePoint == 0x00A5) { - result.append(0x5C); - continue; - } - if (codePoint == 0x203E) { - result.append(0x7E); - continue; - } - if (codePoint >= 0xFF61 && codePoint <= 0xFF9F) { - result.append(codePoint - 0xFF61 + 0xA1); - continue; - } - if (codePoint == 0x2212) - codePoint = 0xFF0D; - - auto range = findInSortedPairs(jis0208EncodeIndex(), codePoint); - if (range.empty()) { - unencodableHandler(codePoint, result); - continue; - } - - ASSERT(range.size() <= 3); - for (auto& pair : range) { - uint16_t pointer = pair.second; - if (pointer >= 8272 && pointer <= 8835) - continue; - uint8_t lead = pointer / 188; - uint8_t leadOffset = lead < 0x1F ? 0x81 : 0xC1; - uint8_t trail = pointer % 188; - uint8_t offset = trail < 0x3F ? 0x40 : 0x41; - result.append(lead + leadOffset); - result.append(trail + offset); - break; - } - } - return result; -} - -using EUCKREncodingIndex = std::array, sizeof(eucKR()) / sizeof(eucKR()[0])>; -static const EUCKREncodingIndex& eucKREncodingIndex() -{ - // Allocate this at runtime because building it at compile time would make the binary much larger and this is often not used. - static EUCKREncodingIndex* table; - static std::once_flag once; - std::call_once(once, [&] { - table = new EUCKREncodingIndex; - auto& index = eucKR(); - for (size_t i = 0; i < index.size(); i++) - (*table)[i] = { index[i].second, index[i].first }; - sortByFirst(*table); - ASSERT(sortedFirstsAreUnique(*table)); - }); - return *table; -} - -// https://encoding.spec.whatwg.org/#euc-kr-encoder -static Vector eucKREncode(StringView string, Function&)>&& unencodableHandler) -{ - Vector result; - result.reserveInitialCapacity(string.length()); - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) { - auto codePoint = *iterator; - if (isASCII(codePoint)) { - result.append(codePoint); - continue; - } - - auto pointer = findFirstInSortedPairs(eucKREncodingIndex(), codePoint); - if (!pointer) { - unencodableHandler(codePoint, result); - continue; - } - result.append(*pointer / 190 + 0x81); - result.append(*pointer % 190 + 0x41); - } - return result; -} - // https://encoding.spec.whatwg.org/#euc-kr-decoder String TextCodecCJK::eucKRDecode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { @@ -775,65 +521,6 @@ String TextCodecCJK::eucKRDecode(std::span bytes, bool flush, boo }); } -using Big5EncodeIndex = std::array, sizeof(big5()) / sizeof(big5()[0]) - 3904>; -static const Big5EncodeIndex& big5EncodeIndex() -{ - // Allocate this at runtime because building it at compile time would make the binary much larger and this is often not used. - static Big5EncodeIndex* table; - static std::once_flag once; - std::call_once(once, [&] { - table = new Big5EncodeIndex; - auto& index = big5(); - // Remove the first 3094 elements because of https://encoding.spec.whatwg.org/#index-big5-pointer - ASSERT(index[3903].first == (0xA1 - 0x81) * 157 - 1); - ASSERT(index[3904].first == (0xA1 - 0x81) * 157); - for (size_t i = 3904; i < index.size(); i++) - (*table)[i - 3904] = { index[i].second, index[i].first }; - stableSortByFirst(*table); - }); - return *table; -} - -// https://encoding.spec.whatwg.org/#big5-encoder -static Vector big5Encode(StringView string, Function&)>&& unencodableHandler) -{ - Vector result; - result.reserveInitialCapacity(string.length()); - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) { - auto codePoint = *iterator; - if (isASCII(codePoint)) { - result.append(codePoint); - continue; - } - - auto range = findInSortedPairs(big5EncodeIndex(), codePoint); - if (range.empty()) { - unencodableHandler(codePoint, result); - continue; - } - - uint16_t pointer = 0; - if (codePoint == 0x2550 || codePoint == 0x255E || codePoint == 0x2561 || codePoint == 0x256A || codePoint == 0x5341 || codePoint == 0x5345) - pointer = range.back().second; - else - pointer = range.front().second; - - if (pointer < 157 * (0xA1 - 0x81)) { - unencodableHandler(codePoint, result); - continue; - } - - uint8_t lead = pointer / 157 + 0x81; - uint8_t trail = pointer % 157; - uint8_t offset = trail < 0x3F ? 0x40 : 0x62; - result.append(lead); - result.append(trail + offset); - } - return result; -} - // https://encoding.spec.whatwg.org/index-gb18030-ranges.txt static const std::array, 207>& gb18030Ranges() { @@ -880,80 +567,6 @@ static std::optional gb18030RangesCodePoint(uint32_t pointer) return codePointOffset + pointer - offset; } -// https://encoding.spec.whatwg.org/#index-gb18030-ranges-pointer -static uint32_t gb18030RangesPointer(char32_t codePoint) -{ - if (codePoint == 0xE7C7) - return 7457; - auto& ranges = gb18030Ranges(); - auto upperBound = std::ranges::upper_bound(ranges, makeSecondAdapter(codePoint), CompareSecond {}); - ASSERT(upperBound != ranges.begin()); - auto [pointerOffset, offset] = ranges[upperBound - ranges.begin() - 1]; - return pointerOffset + codePoint - offset; -} - -using GB18030EncodeIndex = std::array, 23940>; -static const GB18030EncodeIndex& gb18030EncodeIndex() -{ - // Allocate this at runtime because building it at compile time would make the binary much larger and this is often not used. - static GB18030EncodeIndex* table; - static std::once_flag once; - std::call_once(once, [&] { - table = new GB18030EncodeIndex; - auto& index = gb18030(); - for (uint16_t i = 0; i < index.size(); i++) - (*table)[i] = { index[i], i }; - stableSortByFirst(*table); - }); - return *table; -} - -// https://unicode-org.atlassian.net/browse/ICU-22357 -// The 2-byte values are handled correctly by values from gb18030() -// but these need to be exceptions from gb18030Ranges(). -static std::optional gb18030AsymmetricEncode(char32_t codePoint) -{ - switch (codePoint) { - case 0xE81E: - return 0xFE59; - case 0xE826: - return 0xFE61; - case 0xE82B: - return 0xFE66; - case 0xE82C: - return 0xFE67; - case 0xE832: - return 0xFE6D; - case 0xE843: - return 0xFE7E; - case 0xE854: - return 0xFE90; - case 0xE864: - return 0xFEA0; - case 0xE78D: - return 0xA6D9; - case 0xE78F: - return 0xA6DB; - case 0xE78E: - return 0xA6DA; - case 0xE790: - return 0xA6DC; - case 0xE791: - return 0xA6DD; - case 0xE792: - return 0xA6DE; - case 0xE793: - return 0xA6DF; - case 0xE794: - return 0xA6EC; - case 0xE795: - return 0xA6ED; - case 0xE796: - return 0xA6F3; - } - return std::nullopt; -} - // https://encoding.spec.whatwg.org/#gb18030-decoder String TextCodecCJK::gb18030Decode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { @@ -1043,116 +656,12 @@ String TextCodecCJK::gb18030Decode(std::span bytes, bool flush, b return result; } -// https://encoding.spec.whatwg.org/#gb18030-encoder -enum class IsGBK : bool { No, - Yes }; -static Vector gbEncodeShared(StringView string, Function&)>&& unencodableHandler, IsGBK isGBK) -{ - Vector result; - result.reserveInitialCapacity(string.length()); - - auto characters = string.upconvertedCharacters(); - for (WTF::CodePointIterator iterator(characters); !iterator.atEnd(); ++iterator) { - auto codePoint = *iterator; - if (isASCII(codePoint)) { - result.append(codePoint); - continue; - } - if (codePoint == 0xE5E5) { - unencodableHandler(codePoint, result); - continue; - } - if (isGBK == IsGBK::Yes && codePoint == 0x20AC) { - result.append(0x80); - continue; - } - if (auto encoded = gb18030AsymmetricEncode(codePoint)) { - result.append(*encoded >> 8); - result.append(*encoded); - continue; - } - auto range = findInSortedPairs(gb18030EncodeIndex(), codePoint); - if (!range.empty()) { - uint16_t pointer = range[0].second; - uint8_t lead = pointer / 190 + 0x81; - uint8_t trail = pointer % 190; - uint8_t offset = trail < 0x3F ? 0x40 : 0x41; - result.append(lead); - result.append(trail + offset); - continue; - } - if (isGBK == IsGBK::Yes) { - unencodableHandler(codePoint, result); - continue; - } - uint32_t pointer = gb18030RangesPointer(codePoint); - uint8_t byte1 = pointer / (10 * 126 * 10); - pointer = pointer % (10 * 126 * 10); - uint8_t byte2 = pointer / (10 * 126); - pointer = pointer % (10 * 126); - uint8_t byte3 = pointer / 10; - uint8_t byte4 = pointer % 10; - result.append(byte1 + 0x81); - result.append(byte2 + 0x30); - result.append(byte3 + 0x81); - result.append(byte4 + 0x30); - } - return result; -} - -static Vector gb18030Encode(StringView string, Function&)>&& unencodableHandler) -{ - return gbEncodeShared(string, WTF::move(unencodableHandler), IsGBK::No); -} - // https://encoding.spec.whatwg.org/#gbk-decoder String TextCodecCJK::gbkDecode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { return gb18030Decode(bytes, flush, stopOnError, sawError); } -static Vector gbkEncode(StringView string, Function&)>&& unencodableHandler) -{ - return gbEncodeShared(string, WTF::move(unencodableHandler), IsGBK::Yes); -} - -constexpr size_t maxUChar32Digits = 10; - -static void appendDecimal(char32_t c, Vector& result) -{ - std::array::max())> buffer; - writeIntegerToBuffer(c, std::span { buffer }); - result.append(std::span { buffer }.first(lengthOfIntegerAsString(c))); -} - -static void urlEncodedEntityUnencodableHandler(char32_t c, Vector& result) -{ - result.reserveCapacity(result.size() + 9 + maxUChar32Digits); - result.appendList({ '%', '2', '6', '%', '2', '3' }); - appendDecimal(c, result); - result.appendList({ '%', '3', 'B' }); -} - -static void entityUnencodableHandler(char32_t c, Vector& result) -{ - result.reserveCapacity(result.size() + 3 + maxUChar32Digits); - result.appendList({ '&', '#' }); - appendDecimal(c, result); - result.append(';'); -} - -Function&)> unencodableHandler(UnencodableHandling handling) -{ - switch (handling) { - case UnencodableHandling::Entities: - return entityUnencodableHandler; - case UnencodableHandling::URLEncodedEntities: - return urlEncodedEntityUnencodableHandler; - } - ASSERT_NOT_REACHED(); - return entityUnencodableHandler; -} - String TextCodecCJK::big5Decode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { return decodeCommon(bytes, flush, stopOnError, sawError, [this](uint8_t byte, StringBuilder& result) { @@ -1220,26 +729,4 @@ String TextCodecCJK::decode(std::span bytes, bool flush, bool sto return {}; } -Vector TextCodecCJK::encode(StringView string, UnencodableHandling handling) const -{ - switch (m_encoding) { - case Encoding::EUC_JP: - return eucJPEncode(string, unencodableHandler(handling)); - case Encoding::Shift_JIS: - return shiftJISEncode(string, unencodableHandler(handling)); - case Encoding::ISO2022JP: - return iso2022JPEncode(string, unencodableHandler(handling)); - case Encoding::EUC_KR: - return eucKREncode(string, unencodableHandler(handling)); - case Encoding::Big5: - return big5Encode(string, unencodableHandler(handling)); - case Encoding::GBK: - return gbkEncode(string, unencodableHandler(handling)); - case Encoding::GB18030: - return gb18030Encode(string, unencodableHandler(handling)); - } - ASSERT_NOT_REACHED(); - return {}; -} - } // namespace PAL diff --git a/src/jsc/bindings/TextCodecCJK.h b/src/jsc/bindings/TextCodecCJK.h index 71d88f800aa7..ad43c78192d0 100644 --- a/src/jsc/bindings/TextCodecCJK.h +++ b/src/jsc/bindings/TextCodecCJK.h @@ -43,7 +43,6 @@ class TextCodecCJK final : public TextCodec { private: String decode(std::span, bool flush, bool stopOnError, bool& sawError) final; - Vector encode(StringView, UnencodableHandling) const final; enum class SawError : bool { No, Yes }; diff --git a/src/jsc/bindings/TextCodecReplacement.cpp b/src/jsc/bindings/TextCodecReplacement.cpp index 4b25e327b7b3..14aa833139a5 100644 --- a/src/jsc/bindings/TextCodecReplacement.cpp +++ b/src/jsc/bindings/TextCodecReplacement.cpp @@ -64,12 +64,4 @@ String TextCodecReplacement::decode(std::span, bool, bool, bool& return span(replacementCharacter); } -Vector TextCodecReplacement::encode(StringView string, UnencodableHandling) const -{ - // Replacement encoding always fails to encode - // Return empty vector as encoding is not supported - UNUSED_PARAM(string); - return Vector(); -} - } // namespace PAL diff --git a/src/jsc/bindings/TextCodecReplacement.h b/src/jsc/bindings/TextCodecReplacement.h index a94fffe16961..167dabaa3f6a 100644 --- a/src/jsc/bindings/TextCodecReplacement.h +++ b/src/jsc/bindings/TextCodecReplacement.h @@ -39,7 +39,6 @@ class TextCodecReplacement final : public TextCodec { private: String decode(std::span, bool flush, bool stopOnError, bool& sawError) final; - Vector encode(StringView, UnencodableHandling) const final; bool m_sentEOF { false }; }; diff --git a/src/jsc/bindings/TextCodecSingleByte.cpp b/src/jsc/bindings/TextCodecSingleByte.cpp index 82b2b5dcb0c9..729fa4fbe9de 100644 --- a/src/jsc/bindings/TextCodecSingleByte.cpp +++ b/src/jsc/bindings/TextCodecSingleByte.cpp @@ -28,13 +28,10 @@ // config.h removed - not needed in Bun #include "TextCodecSingleByte.h" -#include "EncodingTables.h" #include -#include #include #include #include -#include #include #include @@ -74,8 +71,6 @@ enum class TextCodecSingleByte::Encoding : uint8_t { }; using SingleByteDecodeTable = std::array; -using SingleByteEncodeTableEntry = std::pair; -using SingleByteEncodeTable = std::span; // From https://encoding.spec.whatwg.org/index-iso-8859-3.txt with 0xFFFD filling the gaps static constexpr SingleByteDecodeTable iso88593 { @@ -388,87 +383,6 @@ static constexpr SingleByteDecodeTable xMacCyrillic { 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x20AC }; -template SingleByteEncodeTable tableForEncoding() -{ - // Allocate this at runtime because building it at compile time would make the binary much larger and this is often not used. - static constexpr auto size = std::size(decodeTable) - std::count(std::begin(decodeTable), std::end(decodeTable), replacementCharacter); - static const std::array* entries; - static std::once_flag once; - std::call_once(once, [&] { - auto* mutableEntries = new std::array(); - size_t j = 0; - for (size_t i = 0; i < std::size(decodeTable); ++i) { - if (decodeTable[i] != replacementCharacter) - (*mutableEntries)[j++] = { decodeTable[i], i + 0x80 }; - } - ASSERT(j == size); - auto collection = std::span { *mutableEntries }; - sortByFirst(collection); - ASSERT(sortedFirstsAreUnique(collection)); - entries = mutableEntries; - }); - return std::span { *entries }; -} - -static SingleByteEncodeTable tableForEncoding(TextCodecSingleByte::Encoding encoding) -{ - switch (encoding) { - case TextCodecSingleByte::Encoding::ISO_8859_3: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_6: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_7: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_8: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_874: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1253: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1255: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1257: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::IBM866: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::KOI8U: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_2: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_4: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_5: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_10: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_13: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_14: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_15: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::ISO_8859_16: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::KOI8R: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Macintosh: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1250: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1251: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1254: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1256: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::Windows_1258: - return tableForEncoding(); - case TextCodecSingleByte::Encoding::XMacCyrillic: - return tableForEncoding(); - } - RELEASE_ASSERT_NOT_REACHED(); -} - static const SingleByteDecodeTable& tableForDecoding(TextCodecSingleByte::Encoding encoding) { switch (encoding) { @@ -528,27 +442,6 @@ static const SingleByteDecodeTable& tableForDecoding(TextCodecSingleByte::Encodi RELEASE_ASSERT_NOT_REACHED(); } -// https://encoding.spec.whatwg.org/#single-byte-encoder -static Vector encode(const SingleByteEncodeTable& table, StringView string, Function&)>&& unencodableHandler) -{ - // FIXME: Consider adding an ASCII fast path like the one in TextCodecLatin1::decode. - Vector result; - result.reserveInitialCapacity(string.length()); - for (auto codePoint : string.codePoints()) { - if (isASCII(codePoint)) { - result.append(codePoint); - continue; - } - auto byte = findFirstInSortedPairs(table, codePoint); - if (!byte) { - unencodableHandler(codePoint, result); - continue; - } - result.append(*byte); - } - return result; -} - // https://encoding.spec.whatwg.org/#single-byte-decoder static String decode(const SingleByteDecodeTable& table, std::span bytes, bool, bool stopOnError, bool& sawError) { @@ -577,11 +470,6 @@ static String decode(const SingleByteDecodeTable& table, std::span TextCodecSingleByte::encode(StringView string, UnencodableHandling handling) const -{ - return PAL::encode(tableForEncoding(m_encoding), string, unencodableHandler(handling)); -} - String TextCodecSingleByte::decode(std::span bytes, bool flush, bool stopOnError, bool& sawError) { return PAL::decode(tableForDecoding(m_encoding), bytes, flush, stopOnError, sawError); diff --git a/src/jsc/bindings/TextCodecSingleByte.h b/src/jsc/bindings/TextCodecSingleByte.h index e6104c8c1471..5d24bc050858 100644 --- a/src/jsc/bindings/TextCodecSingleByte.h +++ b/src/jsc/bindings/TextCodecSingleByte.h @@ -42,7 +42,6 @@ class TextCodecSingleByte final : public TextCodec { private: String decode(std::span, bool flush, bool stopOnError, bool& sawError) final; - Vector encode(StringView, UnencodableHandling) const final; const Encoding m_encoding; }; diff --git a/src/jsc/bindings/TextCodecUserDefined.cpp b/src/jsc/bindings/TextCodecUserDefined.cpp index 643b569ddac6..b540376d0f6b 100644 --- a/src/jsc/bindings/TextCodecUserDefined.cpp +++ b/src/jsc/bindings/TextCodecUserDefined.cpp @@ -28,7 +28,6 @@ // config.h removed - not needed in Bun #include "TextCodecUserDefined.h" -#include #include #include #include @@ -65,43 +64,4 @@ String TextCodecUserDefined::decode(std::span bytes, bool, bool, return result.toString(); } -static Vector encodeComplexUserDefined(StringView string, UnencodableHandling handling) -{ - Vector result; - - for (auto character : string.codePoints()) { - int8_t signedByte = character; - if ((signedByte & 0xF7FF) == character) - result.append(signedByte); - else { - // No way to encode this character with x-user-defined. - UnencodableReplacementArray replacement; - result.append(TextCodec::getUnencodableReplacement(character, handling, replacement)); - } - } - - return result; -} - -Vector TextCodecUserDefined::encode(StringView string, UnencodableHandling handling) const -{ - { - Vector result(string.length()); - size_t index = 0; - - // Convert and simultaneously do a check to see if it's all ASCII. - char16_t ored = 0; - for (auto character : string.codeUnits()) { - result[index++] = character; - ored |= character; - } - - if (!(ored & 0xFF80)) - return result; - } - - // If it wasn't all ASCII, call the function that handles more-complex cases. - return encodeComplexUserDefined(string, handling); -} - } // namespace PAL diff --git a/src/jsc/bindings/TextCodecUserDefined.h b/src/jsc/bindings/TextCodecUserDefined.h index 50a284a586b1..cb93d71dbf9c 100644 --- a/src/jsc/bindings/TextCodecUserDefined.h +++ b/src/jsc/bindings/TextCodecUserDefined.h @@ -39,7 +39,6 @@ class TextCodecUserDefined final : public TextCodec { private: String decode(std::span, bool flush, bool stopOnError, bool& sawError) final; - Vector encode(StringView, UnencodableHandling) const final; }; } // namespace PAL diff --git a/src/jsc/bindings/TextCodecWrapper.cpp b/src/jsc/bindings/TextCodecWrapper.cpp index 5aa1bf360c7d..3af8e6db500f 100644 --- a/src/jsc/bindings/TextCodecWrapper.cpp +++ b/src/jsc/bindings/TextCodecWrapper.cpp @@ -70,13 +70,4 @@ void Bun__deleteTextCodec(void* codecPtr) } } -// Strip BOM from codec -void Bun__stripBOMFromTextCodec(void* codecPtr) -{ - if (codecPtr) { - TextCodec* codec = static_cast(codecPtr); - codec->stripByteOrderMark(); - } -} - } // extern "C" diff --git a/src/jsc/bindings/TextEncoding.cpp b/src/jsc/bindings/TextEncoding.cpp index 8dbb32b3c4f9..85b6784b248e 100644 --- a/src/jsc/bindings/TextEncoding.cpp +++ b/src/jsc/bindings/TextEncoding.cpp @@ -30,49 +30,14 @@ // config.h removed - not needed in Bun #include "TextEncoding.h" -#include "TextCodec.h" #include "TextEncodingRegistry.h" -#include #include namespace PAL { -TextEncoding::TextEncoding(ASCIILiteral name) - : m_name(atomCanonicalTextEncodingName(name)) - , m_backslashAsCurrencySymbol(backslashAsCurrencySymbol()) -{ -} - TextEncoding::TextEncoding(StringView name) : m_name(atomCanonicalTextEncodingName(name)) - , m_backslashAsCurrencySymbol(backslashAsCurrencySymbol()) -{ -} - -String TextEncoding::decode(std::span data, bool stopOnError, bool& sawError) const -{ - if (m_name.isNull()) - return String(); - - return newTextCodec(*this)->decode(data, true, stopOnError, sawError); -} - -Vector TextEncoding::encode(StringView string, PAL::UnencodableHandling handling, NFCNormalize normalize) const -{ - if (m_name.isNull() || string.isEmpty()) - return {}; - - // FIXME: What's the right place to do normalization? - // It's a little strange to do it inside the encode function. - // Perhaps normalization should be an explicit step done before calling encode. - if (normalize == NFCNormalize::Yes) - return newTextCodec(*this)->encode(normalizedNFC(string).view, handling); - return newTextCodec(*this)->encode(string, handling); -} - -char16_t TextEncoding::backslashAsCurrencySymbol() const { - return shouldShowBackslashAsCurrencySymbolIn(m_name) ? 0x00A5 : '\\'; } } // namespace PAL diff --git a/src/jsc/bindings/TextEncoding.h b/src/jsc/bindings/TextEncoding.h index d3c9389516d2..7dc298ae0980 100644 --- a/src/jsc/bindings/TextEncoding.h +++ b/src/jsc/bindings/TextEncoding.h @@ -25,8 +25,7 @@ #pragma once -#include "UnencodableHandling.h" -#include +#include #include #ifndef PAL_EXPORT @@ -35,34 +34,16 @@ namespace PAL { -enum class NFCNormalize : bool { No, - Yes }; - -class TextEncoding : public WTF::URLTextEncoding { +class TextEncoding { public: TextEncoding() = default; - PAL_EXPORT TextEncoding(ASCIILiteral name); PAL_EXPORT TextEncoding(StringView name); bool isValid() const { return !m_name.isNull(); } ASCIILiteral name() const { return m_name; } - PAL_EXPORT String decode(std::span, bool stopOnError, bool& sawError) const; - String decode(std::span) const; - PAL_EXPORT Vector encode(StringView, PAL::UnencodableHandling, NFCNormalize = NFCNormalize::Yes) const; - Vector encodeForURLParsing(StringView string) const final { return encode(string, PAL::UnencodableHandling::URLEncodedEntities, NFCNormalize::No); } - - char16_t backslashAsCurrencySymbol() const; - private: ASCIILiteral m_name; - char16_t m_backslashAsCurrencySymbol; }; -inline String TextEncoding::decode(std::span characters) const -{ - bool ignored; - return decode(characters, false, ignored); -} - } // namespace PAL diff --git a/src/jsc/bindings/TextEncodingRegistry.cpp b/src/jsc/bindings/TextEncodingRegistry.cpp index a8b3ffe3229b..a836391b5a0d 100644 --- a/src/jsc/bindings/TextEncodingRegistry.cpp +++ b/src/jsc/bindings/TextEncodingRegistry.cpp @@ -42,11 +42,11 @@ #include "TextCodecSingleByte.h" #include "TextCodecUserDefined.h" #include "TextEncoding.h" +#include #include #include #include #include -#include #include #include #include @@ -132,12 +132,6 @@ static TextCodecMap& textCodecMap() WTF_REQUIRES_LOCK(encodingRegistryLock) } static bool didExtendTextCodecMaps; -static HashSet& nonBackslashEncodings() -{ - static NeverDestroyed> nonBackslashEncodings; - return nonBackslashEncodings; -} - static constexpr ASCIILiteral textEncodingNameBlocklist[] = { "UTF-7"_s, "BOCU-1"_s, "SCSU"_s }; static bool isUndesiredAlias(ASCIILiteral alias) @@ -209,35 +203,6 @@ static void buildBaseTextCodecMaps() WTF_REQUIRES_LOCK(encodingRegistryLock) TextCodecUserDefined::registerCodecs(addToTextCodecMap); } -static void addEncodingName(HashSet& set, ASCIILiteral name) WTF_REQUIRES_LOCK(encodingRegistryLock) -{ - // We must not use atomCanonicalTextEncodingName() because this function is called in it. - ASCIILiteral atomName = textEncodingNameMap().get(name); - if (!atomName.isNull()) - set.add(atomName); -} - -static void buildQuirksSets() WTF_REQUIRES_LOCK(encodingRegistryLock) -{ - auto& nonBackslashEncodings = PAL::nonBackslashEncodings(); - - ASSERT(nonBackslashEncodings.isEmpty()); - - // The text encodings below treat backslash as a currency symbol for IE compatibility. - // See http://blogs.msdn.com/michkap/archive/2005/09/17/469941.aspx for more information. - addEncodingName(nonBackslashEncodings, "x-mac-japanese"_s); - addEncodingName(nonBackslashEncodings, "ISO-2022-JP"_s); - addEncodingName(nonBackslashEncodings, "EUC-JP"_s); - // Shift_JIS_X0213-2000 is not the same encoding as Shift_JIS on Mac. We need to register both of them. - addEncodingName(nonBackslashEncodings, "Shift_JIS"_s); - addEncodingName(nonBackslashEncodings, "Shift_JIS_X0213-2000"_s); -} - -bool shouldShowBackslashAsCurrencySymbolIn(ASCIILiteral canonicalEncodingName) -{ - return !canonicalEncodingName.isNull() && nonBackslashEncodings().contains(canonicalEncodingName); -} - static void extendTextCodecMaps() WTF_REQUIRES_LOCK(encodingRegistryLock) { TextCodecReplacement::registerEncodingNames(addToTextEncodingNameMap); @@ -254,7 +219,6 @@ static void extendTextCodecMaps() WTF_REQUIRES_LOCK(encodingRegistryLock) TextCodecSingleByte::registerCodecs(addToTextCodecMap); pruneBlocklistedCodecs(); - buildQuirksSets(); } std::unique_ptr newTextCodec(const TextEncoding& encoding) @@ -312,11 +276,6 @@ static ASCIILiteral atomCanonicalTextEncodingName(std::span char return atomCanonicalTextEncodingName(std::span { buffer }.first(characters.size())); } -ASCIILiteral atomCanonicalTextEncodingName(ASCIILiteral name) -{ - return atomCanonicalTextEncodingName(name.span8()); -} - ASCIILiteral atomCanonicalTextEncodingName(StringView alias) { if (alias.isEmpty() || !alias.containsOnlyASCII()) diff --git a/src/jsc/bindings/TextEncodingRegistry.h b/src/jsc/bindings/TextEncodingRegistry.h index 263791097d2d..be1783bf7d37 100644 --- a/src/jsc/bindings/TextEncodingRegistry.h +++ b/src/jsc/bindings/TextEncodingRegistry.h @@ -37,13 +37,9 @@ namespace PAL { class TextCodec; class TextEncoding; -// Use TextResourceDecoder::decode to decode resources, since it handles BOMs. -// Use TextEncoding::encode to encode, since it takes care of normalization. PAL_EXPORT std::unique_ptr newTextCodec(const TextEncoding&); -// Only TextEncoding should use the following functions directly. -ASCIILiteral atomCanonicalTextEncodingName(ASCIILiteral alias); +// Only TextEncoding should use the following function directly. ASCIILiteral atomCanonicalTextEncodingName(StringView); -bool shouldShowBackslashAsCurrencySymbolIn(ASCIILiteral canonicalEncodingName); } // namespace PAL diff --git a/src/jsc/bindings/UnencodableHandling.h b/src/jsc/bindings/UnencodableHandling.h deleted file mode 100644 index 86c031e7ed14..000000000000 --- a/src/jsc/bindings/UnencodableHandling.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2004-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -namespace PAL { - -// Specifies what will happen when a character is encountered that is -// not encodable in the character set. -enum class UnencodableHandling : bool { - // Encodes the character as an XML entity. For example, U+06DE - // would be "۞" (0x6DE = 1758 in octal). - Entities, - - // Encodes the character as en entity as above, but escaped - // non-alphanumeric characters. This is used in URLs. - // For example, U+6DE would be "%26%231758%3B". - URLEncodedEntities -}; - -} diff --git a/src/jsc/bindings/headers-handwritten.h b/src/jsc/bindings/headers-handwritten.h index 1d1cf5dc7c8f..699d909ad7fd 100644 --- a/src/jsc/bindings/headers-handwritten.h +++ b/src/jsc/bindings/headers-handwritten.h @@ -383,11 +383,6 @@ extern "C" bool Bun__VM__useIsolationSourceProviderCache(void* bunVM); extern "C" const char* Bun__version; extern "C" const char* Bun__version_with_sha; -// Version exports removed - now handled by CMake-generated header (bun_dependency_versions.h) -// Only keep the ones still exported from native code -extern "C" const char* Bun__versions_uws; -extern "C" const char* Bun__versions_usockets; - extern "C" const char* Bun__version_sha; extern "C" void ZigString__freeGlobal(const unsigned char* ptr, size_t len); diff --git a/src/jsc/modules/BunJSCModule.h b/src/jsc/modules/BunJSCModule.h index bc3fdb1ead32..4b89e7a19c74 100644 --- a/src/jsc/modules/BunJSCModule.h +++ b/src/jsc/modules/BunJSCModule.h @@ -956,62 +956,11 @@ JSC_DEFINE_HOST_FUNCTION(functionEstimateDirectMemoryUsageOf, (JSGlobalObject * return JSValue::encode(jsNumber(0)); } -#if USE(BMALLOC_MEMORY_FOOTPRINT_API) - -#include - -JSC_DEFINE_HOST_FUNCTION(functionPercentAvailableMemoryInUse, (JSGlobalObject * globalObject, CallFrame* callFrame)) -{ - return JSValue::encode(jsDoubleNumber(bmalloc::api::percentAvailableMemoryInUse())); -} - -#else - JSC_DEFINE_HOST_FUNCTION(functionPercentAvailableMemoryInUse, (JSGlobalObject * globalObject, CallFrame* callFrame)) { return JSValue::encode(jsNull()); } -#endif - -// clang-format off -/* Source for BunJSCModuleTable.lut.h -@begin BunJSCModuleTable - callerSourceOrigin functionCallerSourceOrigin Function 0 - jscDescribe functionDescribe Function 0 - jscDescribeArray functionDescribeArray Function 0 - drainMicrotasks functionDrainMicrotasks Function 0 - edenGC functionEdenGC Function 0 - fullGC functionFullGC Function 0 - gcAndSweep functionGCAndSweep Function 0 - getRandomSeed functionGetRandomSeed Function 0 - heapSize functionHeapSize Function 0 - heapStats functionMemoryUsageStatistics Function 0 - startSamplingProfiler functionStartSamplingProfiler Function 0 - samplingProfilerStackTraces functionSamplingProfilerStackTraces Function 0 - noInline functionNeverInlineFunction Function 0 - isRope functionIsRope Function 0 - memoryUsage functionCreateMemoryFootprint Function 0 - noFTL functionNoFTL Function 0 - noOSRExitFuzzing functionNoOSRExitFuzzing Function 0 - numberOfDFGCompiles functionNumberOfDFGCompiles Function 0 - optimizeNextInvocation functionOptimizeNextInvocation Function 0 - releaseWeakRefs functionReleaseWeakRefs Function 0 - reoptimizationRetryCount functionReoptimizationRetryCount Function 0 - setRandomSeed functionSetRandomSeed Function 0 - startRemoteDebugger functionStartRemoteDebugger Function 0 - totalCompileTime functionTotalCompileTime Function 0 - getProtectedObjects functionGetProtectedObjects Function 0 - generateHeapSnapshotForDebugging functionGenerateHeapSnapshotForDebugging Function 0 - profile functionRunProfiler Function 0 - setTimeZone functionSetTimeZone Function 0 - serialize functionSerialize Function 0 - deserialize functionDeserialize Function 0 - estimateShallowMemoryUsageOf functionEstimateDirectMemoryUsageOf Function 1 - percentAvailableMemoryInUse functionPercentAvailableMemoryInUse Function 0 -@end -*/ - namespace Zig { DEFINE_NATIVE_MODULE(BunJSC) { @@ -1044,7 +993,7 @@ DEFINE_NATIVE_MODULE(BunJSC) putNativeFn(Identifier::fromString(vm, "getProtectedObjects"_s), functionGetProtectedObjects); putNativeFn(Identifier::fromString(vm, "generateHeapSnapshotForDebugging"_s), functionGenerateHeapSnapshotForDebugging); putNativeFn(Identifier::fromString(vm, "profile"_s), functionRunProfiler); - putNativeFn(Identifier::fromString(vm, "codeCoverageForFile"_s), functionCodeCoverageForFile); + putNativeFn(Identifier::fromString(vm, "codeCoverageForFile"_s), functionCodeCoverageForFile); putNativeFn(Identifier::fromString(vm, "setTimeZone"_s), functionSetTimeZone); putNativeFn(Identifier::fromString(vm, "serialize"_s), functionSerialize); putNativeFn(Identifier::fromString(vm, "deserialize"_s), functionDeserialize); diff --git a/src/runtime/api/zlib.classes.ts b/src/runtime/api/zlib.classes.ts index 074de35a1557..b216ffe79191 100644 --- a/src/runtime/api/zlib.classes.ts +++ b/src/runtime/api/zlib.classes.ts @@ -10,7 +10,7 @@ function generate(name: string) { estimatedSize: true, klass: {}, JSType: "0b11101110", - values: ["writeCallback", "errorCallback", "dictionary", "pendingInput", "pendingOutput", "writeResult"], + values: ["writeCallback", "errorCallback", "pendingInput", "pendingOutput", "writeResult"], proto: { init: { fn: "init" }, diff --git a/src/runtime/cli/pack_command.rs b/src/runtime/cli/pack_command.rs index 3331c3cf693c..1490b3cd74ca 100644 --- a/src/runtime/cli/pack_command.rs +++ b/src/runtime/cli/pack_command.rs @@ -382,15 +382,6 @@ pub(crate) struct PackQueueItem { optional: bool, } -impl Default for PackQueueItem { - fn default() -> Self { - Self { - path: ZBox::from_bytes(b""), - optional: false, - } - } -} - // `bun_collections` has no `PriorityQueue`; wrap `BinaryHeap` with a reversed `Ord` // (BinaryHeap is a max-heap, so invert `strings::order` to pop smallest first). impl Ord for PackQueueItem { diff --git a/src/runtime/cli/test/Scanner.rs b/src/runtime/cli/test/Scanner.rs index 1f54f36f8794..dab434963f6d 100644 --- a/src/runtime/cli/test/Scanner.rs +++ b/src/runtime/cli/test/Scanner.rs @@ -46,7 +46,7 @@ pub struct ScanEntry { pub name: StringOrTinyString, } -#[derive(thiserror::Error, Debug, strum::IntoStaticStr)] +#[derive(thiserror::Error, Debug)] pub enum ScanError { /// Scan entrypoint file/directory does not exist. Not returned when /// a subdirectory is scanned but does not exist. @@ -56,11 +56,6 @@ pub enum ScanError { OutOfMemory, } bun_core::oom_from_alloc!(ScanError); -impl PartialEq for ScanError { - fn eq(&self, other: &crate::Error) -> bool { - <&'static str>::from(self) == other.name() - } -} /// Newtype around `*mut Scanner` so it can satisfy [`DirEntryIterator`] /// (whose `next` takes `&self`) while still allowing mutable calls. diff --git a/src/runtime/cli/test/parallel/Worker.rs b/src/runtime/cli/test/parallel/Worker.rs index 7030ed3b3839..2540573682b0 100644 --- a/src/runtime/cli/test/parallel/Worker.rs +++ b/src/runtime/cli/test/parallel/Worker.rs @@ -428,12 +428,6 @@ impl WorkerPipe { } } -impl Default for WorkerPipe { - fn default() -> Self { - Self::new(core::ptr::null()) - } -} - // `bun_io::BufferedReader` vtable parent. // Callbacks touch only fields disjoint from `reader` (worker backref / done // flag); worker/coord backrefs are valid for the pipe's lifetime. @@ -447,9 +441,3 @@ bun_io::impl_buffered_reader_parent! { loop_ = |this| (*(*(*this).worker).coord).vm.uv_loop(); event_loop = |this| (*(*(*this).worker).coord).event_loop_handle.as_event_loop_ctx(); } - -impl Drop for WorkerPipe { - fn drop(&mut self) { - // Body intentionally empty: `BufferedReader: Drop` handles cleanup. - } -} diff --git a/src/runtime/cli/which_npm_client.rs b/src/runtime/cli/which_npm_client.rs index fe73189c571b..435dbc300d57 100644 --- a/src/runtime/cli/which_npm_client.rs +++ b/src/runtime/cli/which_npm_client.rs @@ -16,9 +16,3 @@ impl Tag { } } } - -impl From for &'static str { - fn from(t: Tag) -> &'static str { - t.as_str() - } -} diff --git a/src/runtime/crypto/CryptoHasher.rs b/src/runtime/crypto/CryptoHasher.rs index f2e0f2bc02f4..04e8a940737a 100644 --- a/src/runtime/crypto/CryptoHasher.rs +++ b/src/runtime/crypto/CryptoHasher.rs @@ -1109,12 +1109,11 @@ impl CryptoHasherZig { // ─────────────────────────────────────────────────────────────────────────── /// Trait abstracting over the `bun_sha_hmac::sha::evp::*` hasher types. -/// When `HAS_ENGINE` is true, `hash()` takes a BoringSSL ENGINE*. +/// `hash()` takes the VM-owned BoringSSL ENGINE*. pub trait StaticHasher: 'static { const NAME: &'static str; const DIGEST: usize; type Digest: AsRef<[u8]> + AsMut<[u8]>; // = [u8; Self::DIGEST] - const HAS_ENGINE: bool; fn init() -> Self; fn new_digest() -> Self::Digest; @@ -1138,7 +1137,6 @@ macro_rules! impl_static_hasher { const NAME: &'static str = $name; const DIGEST: usize = $len; type Digest = [u8; $len]; - const HAS_ENGINE: bool = true; #[inline] fn init() -> Self { @@ -1307,14 +1305,8 @@ impl StaticCryptoHasher { } // SAFETY: `boring_engine` returns the VM-owned engine (live for the - // process) or null; the else arm passes null. - unsafe { - if H::HAS_ENGINE { - H::hash(input.slice(), &mut output_digest_buf, boring_engine(global)); - } else { - H::hash(input.slice(), &mut output_digest_buf, core::ptr::null_mut()); - } - } + // process) or null. + unsafe { H::hash(input.slice(), &mut output_digest_buf, boring_engine(global)) }; encoding.encode_with_max_size(global, EVP_MAX_MD_SIZE_USIZE, output_digest_buf.as_ref()) } @@ -1344,14 +1336,8 @@ impl StaticCryptoHasher { } // SAFETY: `boring_engine` returns the VM-owned engine (live for the - // process) or null; the else arm passes null. - unsafe { - if H::HAS_ENGINE { - H::hash(input.slice(), output_digest_slice, boring_engine(global)); - } else { - H::hash(input.slice(), output_digest_slice, core::ptr::null_mut()); - } - } + // process) or null. + unsafe { H::hash(input.slice(), output_digest_slice, boring_engine(global)) }; if let Some(output_buf) = output { Ok(output_buf.value) diff --git a/src/runtime/node/node_fs_stat_watcher.rs b/src/runtime/node/node_fs_stat_watcher.rs index 651d661d57f9..9b321015da57 100644 --- a/src/runtime/node/node_fs_stat_watcher.rs +++ b/src/runtime/node/node_fs_stat_watcher.rs @@ -21,6 +21,7 @@ use bun_resolver::fs; use bun_sys::{self, PosixStat}; use bun_threading::{Guarded, UnboundedQueue}; +use crate::generated_classes::js_StatWatcher as js; use crate::node::stat::{StatsBig, StatsSmall}; use crate::node::types::PathLikeExt; use crate::timer::{EventLoopTimer, EventLoopTimerState, EventLoopTimerTag}; @@ -525,64 +526,6 @@ pub struct StatWatcher { scheduler: RefPtr, } -/// `jsc.Codegen.JSStatWatcher` — cached-value accessors generated from -/// `.classes.ts`. The C++ symbols are emitted by `generate-classes.ts`; this -/// module declares them locally so callers can write `js::listener_get_cached` -/// without depending on the placeholder type in `crate::generated_classes`. -mod js { - use super::{JSGlobalObject, JSValue}; - - // `safe fn` to match the `safe fn …CachedValue` declarations - // `generate-classes.ts` emits in `generated_classes.rs` (avoids - // `clashing_extern_declarations`). C++ side declares these with - // `JSC_CALLCONV` (= SysV ABI on win-x64), so import via `jsc_abi_extern!` - // — a plain `extern "C"` block here is the wrong ABI on Windows and - // garbages the args (Win64 puts them in rcx/rdx/r8, callee reads rdi/rsi/rdx). - bun_jsc::jsc_abi_extern! { - safe fn StatWatcherPrototype__listenerSetCachedValue( - this_value: JSValue, - global: *mut JSGlobalObject, - value: JSValue, - ); - safe fn StatWatcherPrototype__listenerGetCachedValue(this_value: JSValue) -> JSValue; - safe fn StatWatcherPrototype__prevStatSetCachedValue( - this_value: JSValue, - global: *mut JSGlobalObject, - value: JSValue, - ); - safe fn StatWatcherPrototype__prevStatGetCachedValue(this_value: JSValue) -> JSValue; - } - - #[inline] - pub(super) fn listener_set_cached( - this_value: JSValue, - global: &JSGlobalObject, - value: JSValue, - ) { - StatWatcherPrototype__listenerSetCachedValue(this_value, global.as_mut_ptr(), value) - } - #[inline] - pub(super) fn listener_get_cached(this_value: JSValue) -> Option { - let v = StatWatcherPrototype__listenerGetCachedValue(this_value); - if v.is_empty() { None } else { Some(v) } - } - - pub(super) mod gc { - pub(crate) mod prev_stat { - use super::super::*; - #[inline] - pub(crate) fn set(this_value: JSValue, global: &JSGlobalObject, value: JSValue) { - StatWatcherPrototype__prevStatSetCachedValue(this_value, global.as_mut_ptr(), value) - } - #[inline] - pub(crate) fn get(this_value: JSValue) -> Option { - let v = StatWatcherPrototype__prevStatGetCachedValue(this_value); - if v.is_empty() { None } else { Some(v) } - } - } - } -} - impl StatWatcher { /// Safe `&JSGlobalObject` accessor for the JSC_BORROW `global_this` back-pointer. #[inline] @@ -845,7 +788,7 @@ impl StatWatcher { // Propagated to the task fold: reporting here would leave a // termination pending for the next queued task's JS entry. let jsvalue = stat_to_js_stats(global_this, &this_ref.get_last_stat(), this_ref.bigint)?; - js::gc::prev_stat::set(js_this, global_this, jsvalue); + js::prev_stat_set_cached(js_this, global_this, jsvalue); // SAFETY: scheduler is live (`RefPtr`); `this` is live (ref'd, guard above). StatWatcherScheduler::append(this_ref.scheduler.as_ptr(), this); @@ -870,7 +813,7 @@ impl StatWatcher { }; let global_this = this_ref.global_this(); let jsvalue = stat_to_js_stats(global_this, &this_ref.get_last_stat(), this_ref.bigint)?; - js::gc::prev_stat::set(js_this, global_this, jsvalue); + js::prev_stat_set_cached(js_this, global_this, jsvalue); let result = js::listener_get_cached(js_this).unwrap().call( global_this, @@ -955,10 +898,10 @@ impl StatWatcher { return Ok(()); }; let global_this = this_ref.global_this(); - let prev_jsvalue = js::gc::prev_stat::get(js_this).unwrap_or(JSValue::UNDEFINED); + let prev_jsvalue = js::prev_stat_get_cached(js_this).unwrap_or(JSValue::UNDEFINED); let current_jsvalue = stat_to_js_stats(global_this, &this_ref.get_last_stat(), this_ref.bigint)?; - js::gc::prev_stat::set(js_this, global_this, current_jsvalue); + js::prev_stat_set_cached(js_this, global_this, current_jsvalue); // Propagate to the dispatcher: `report_error_or_terminate` reports a // regular throw as uncaught and stops the tick loop on termination. diff --git a/src/runtime/node/node_process.rs b/src/runtime/node/node_process.rs index d021b241ea51..df6df1bd61d3 100644 --- a/src/runtime/node/node_process.rs +++ b/src/runtime/node/node_process.rs @@ -163,20 +163,6 @@ static Bun__version_with_sha: CStrPtr = CStrPtr( .as_ptr() .cast::(), ); -// Version exports removed - now handled by build-generated header (bun_dependency_versions.h) -// The C++ code in BunProcess.cpp uses the generated header directly -#[unsafe(no_mangle)] -static Bun__versions_uws: CStrPtr = CStrPtr( - const_format::concatcp!(Environment::GIT_SHA, "\0") - .as_ptr() - .cast::(), -); -#[unsafe(no_mangle)] -static Bun__versions_usockets: CStrPtr = CStrPtr( - const_format::concatcp!(Environment::GIT_SHA, "\0") - .as_ptr() - .cast::(), -); #[unsafe(no_mangle)] static Bun__version_sha: CStrPtr = CStrPtr( const_format::concatcp!(Environment::GIT_SHA, "\0") diff --git a/src/runtime/node/node_zlib_binding.rs b/src/runtime/node/node_zlib_binding.rs index 2772bc734128..64c281d407fb 100644 --- a/src/runtime/node/node_zlib_binding.rs +++ b/src/runtime/node/node_zlib_binding.rs @@ -1006,7 +1006,7 @@ pub(crate) fn native_zstd(global: &JSGlobalObject) -> JSValue { /// /// `$type_name` is the C++-side class name (matches `.classes.ts`); the macro /// emits a `pub mod js { … }` with the cached-property accessors -/// (`writeCallback` / `errorCallback` / `dictionary`) wired to the +/// (`writeCallback` / `errorCallback` / …) wired to the /// `${TypeName}Prototype__${prop}{Get,Set}CachedValue` extern symbols. #[macro_export] #[doc(hidden)] @@ -1026,7 +1026,7 @@ macro_rules! __impl_compression_stream { /// `generate-classes.ts` for the `values:` list in `zlib.classes.ts`. #[allow(unused)] pub(crate) mod js { - ::bun_jsc::codegen_cached_accessors!($type_name; writeCallback, errorCallback, dictionary, pendingInput, pendingOutput, writeResult); + ::bun_jsc::codegen_cached_accessors!($type_name; writeCallback, errorCallback, pendingInput, pendingOutput, writeResult); } impl $crate::node::node_zlib_binding::CompressionContext for $ctx { diff --git a/src/runtime/node/zlib/NativeZlib.rs b/src/runtime/node/zlib/NativeZlib.rs index 1a302200a96f..399c3772a69e 100644 --- a/src/runtime/node/zlib/NativeZlib.rs +++ b/src/runtime/node/zlib/NativeZlib.rs @@ -28,7 +28,7 @@ mod _impl { /// struct-init site; the body never dereferences the pointer. fn noop_task_callback(_task: *mut WorkPoolTask) {} - // `mod js { write_callback_*, error_callback_*, dictionary_* }` is emitted by + // `mod js { write_callback_*, error_callback_*, ... }` is emitted by // `__impl_compression_stream!` below (wraps `bun_jsc::codegen_cached_accessors!`). /// `bun.ptr.RefCount(@This(), "ref_count", deinit, .{})` — intrusive single-thread refcount. diff --git a/src/runtime/shell/IO.rs b/src/runtime/shell/IO.rs index fdfd9e652271..f5254fde114a 100644 --- a/src/runtime/shell/IO.rs +++ b/src/runtime/shell/IO.rs @@ -3,7 +3,6 @@ //! `IO` is a plain `Clone` value; `IOReader`/`IOWriter` are `Arc`-refcounted. use bun_collections::VecExt; -use core::fmt; use crate::api::bun_spawn::stdio::{Capture, Stdio}; use crate::shell::interpreter::OutputNeedsIOSafeGuard; @@ -18,16 +17,6 @@ pub struct IO { pub(crate) stderr: OutKind, } -impl fmt::Display for IO { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "stdin: {}\nstdout: {}\nstderr: {}", - self.stdin, self.stdout, self.stderr - ) - } -} - impl IO { /// Sum of stdin/stdout/stderr. pub(crate) fn memory_cost(&self) -> usize { @@ -56,15 +45,6 @@ pub enum InKind { Ignore, } -impl fmt::Display for InKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - InKind::Fd(_) => write!(f, "fd"), - InKind::Ignore => write!(f, "ignore"), - } - } -} - /// Write to a file descriptor (via `IOWriter`), tee into a captured buffer, /// pipe to a subprocess, or drop. #[derive(Clone, Default)] @@ -107,16 +87,6 @@ impl OutFd { } } -impl fmt::Display for OutKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - OutKind::Fd(_) => write!(f, "fd"), - OutKind::Pipe => write!(f, "pipe"), - OutKind::Ignore => write!(f, "ignore"), - } - } -} - impl InKind { fn memory_cost(&self) -> usize { match self { diff --git a/src/runtime/socket/SocketAddress.rs b/src/runtime/socket/SocketAddress.rs index fd9432d61216..32f53670fdaa 100644 --- a/src/runtime/socket/SocketAddress.rs +++ b/src/runtime/socket/SocketAddress.rs @@ -34,15 +34,6 @@ pub struct SocketAddress { _presentation: Cell, } -impl Default for SocketAddress { - fn default() -> Self { - Self { - _addr: sockaddr::LOOPBACK_V4, - _presentation: Cell::new(BunString::dead()), - } - } -} - impl SocketAddress { pub(crate) fn new(init: SocketAddress) -> Box { Box::new(init) diff --git a/src/runtime/test_runner/ScopeFunctions.rs b/src/runtime/test_runner/ScopeFunctions.rs index 340d7151a1e3..5f8b6607738d 100644 --- a/src/runtime/test_runner/ScopeFunctions.rs +++ b/src/runtime/test_runner/ScopeFunctions.rs @@ -541,11 +541,6 @@ pub struct ParseArgumentsCfg { pub callback: CallbackMode, pub(crate) kind: FunctionKind, } -impl Default for ParseArgumentsCfg { - fn default() -> Self { - Self { callback: CallbackMode::Require, kind: FunctionKind::TestOrDescribe } - } -} fn get_description( global: &JSGlobalObject, diff --git a/src/runtime/timer/TimeoutObject.rs b/src/runtime/timer/TimeoutObject.rs index 1bb093137b21..5fd26f857fea 100644 --- a/src/runtime/timer/TimeoutObject.rs +++ b/src/runtime/timer/TimeoutObject.rs @@ -1,29 +1,8 @@ +use bun_jsc::generated::JSTimeout as js; use bun_jsc::{CallFrame, JSGlobalObject, JSValue, JsResult}; use super::Kind; -/// `jsc.Codegen.JSTimeout` — the `.classes.ts` codegen module for this type. -/// -/// `toJS` / `fromJS` / `fromJSDirect` and the `Timeout__create` / -/// `Timeout__fromJS` / `Timeout__fromJSDirect` externs are emitted by -/// `#[bun_jsc::JsClass(name = "Timeout")]` on the struct below (see -/// `jsc_macros::js_class_hooks`); only the cached-property accessors — -/// `${name}GetCached` / `${name}SetCached` per `cache: true` prop — are -/// declared here. -pub mod js { - // One `${snake}_get_cached` / `${snake}_set_cached` pair per cached prop, - // each wrapping `TimeoutPrototype__${prop}{Get,Set}CachedValue` and mapping - // `.zero` → `None` on the get side. - bun_jsc::codegen_cached_accessors!( - "Timeout"; - arguments, - callback, - idleTimeout, - repeat, - idleStart, - ); -} - // Struct + `RefCounted`/`Default` impls + the forwarder host-fns // (`to_primitive`/`do_ref`/`do_unref`/`has_ref`/`get_destroyed`/`dispose`/ // `constructor`/`finalize`/`ref_`/`deref`/`deinit`/`init_with`) — see diff --git a/src/runtime/valkey_jsc/ValkeyCommand.rs b/src/runtime/valkey_jsc/ValkeyCommand.rs index abcc35864f62..d7dc158f2437 100644 --- a/src/runtime/valkey_jsc/ValkeyCommand.rs +++ b/src/runtime/valkey_jsc/ValkeyCommand.rs @@ -22,16 +22,6 @@ pub struct Command<'a> { pub(crate) meta: Meta, } -impl<'a> Default for Command<'a> { - fn default() -> Self { - Self { - command: b"", - args: Args::default(), - meta: Meta::default(), - } - } -} - #[derive(Copy, Clone)] pub enum Args<'a> { Slices(&'a [Slice]), @@ -39,12 +29,6 @@ pub enum Args<'a> { Raw(&'a [&'a [u8]]), } -impl<'a> Default for Args<'a> { - fn default() -> Self { - Args::Raw(&[]) - } -} - impl<'a> Args<'a> { fn len(&self) -> usize { match self { diff --git a/src/runtime/valkey_jsc/js_valkey.rs b/src/runtime/valkey_jsc/js_valkey.rs index d5f4daa7ac0f..b67990ff1b0a 100644 --- a/src/runtime/valkey_jsc/js_valkey.rs +++ b/src/runtime/valkey_jsc/js_valkey.rs @@ -274,25 +274,6 @@ impl JSValkeyClient { } Ok(()) } - - fn subscription_ctx_is_deletable(&self) -> bool { - // The user may request .close(), in which case we can dispose of the subscription object. - // If that is the case, finalized will be true. Otherwise, we should treat the object as - // disposable if there are no active subscriptions. - self.client.get().flags.finalized || !self.has_subscriptions() - } - - pub fn close_subscription_ctx(&self, global_object: &JSGlobalObject) { - debug_assert!(self.subscription_ctx_is_deletable()); - - if let Some(parent_this) = self.this_value.get().try_get() { - Js::subscription_callback_map_set_cached( - parent_this, - global_object, - JSValue::UNDEFINED, - ); - } - } } // ─────────────────────────────────────────────────────────────────────────── diff --git a/src/runtime/valkey_jsc/valkey.rs b/src/runtime/valkey_jsc/valkey.rs index ff8d11287b11..968f75fa1375 100644 --- a/src/runtime/valkey_jsc/valkey.rs +++ b/src/runtime/valkey_jsc/valkey.rs @@ -4,6 +4,7 @@ use bun_collections::VecExt; // This file contains the core Valkey client implementation with protocol handling use bun_collections::OffsetByteList; +use bun_core::UnwrapOrOom; use bun_jsc::virtual_machine::VirtualMachine; use bun_jsc::{GlobalRef, JSGlobalObject, JSPromise, JSValue, JsResult}; use bun_uws::{self as uws, AnySocket, SocketGroup, SocketKind, SslCtx}; @@ -1621,19 +1622,3 @@ impl bun_io::Write for WriteBufWriter<'_> { .map_err(|_| bun_core::Error::Alloc(bun_alloc::AllocError)) } } - -// Local extension trait providing `.unwrap_or_oom()` on `Result`. -// No shared `UnwrapOrOom` trait exists yet (bun_alloc has none); delegate to -// `bun_core::handle_oom` so every call site keeps its method-chain shape. -trait UnwrapOrOom { - type Output; - fn unwrap_or_oom(self) -> Self::Output; -} -impl UnwrapOrOom for core::result::Result { - type Output = T; - #[inline] - #[track_caller] - fn unwrap_or_oom(self) -> T { - bun_core::handle_oom(self) - } -} diff --git a/src/runtime/webcore/TextDecoder.rs b/src/runtime/webcore/TextDecoder.rs index 1371509aae47..2dbc86b53790 100644 --- a/src/runtime/webcore/TextDecoder.rs +++ b/src/runtime/webcore/TextDecoder.rs @@ -506,11 +506,6 @@ impl TextDecoder { // Fallback to empty string if codec creation fails return Ok(ZigString::init(b"").to_js(global_this)); }; - if !self.ignore_bom { - // `TextCodec` is an opaque ZST FFI handle (S008); - // `ptr` is live — safe via `opaque_deref_mut`. - bun_opaque::opaque_deref_mut(ptr.as_ptr()).strip_bom(); - } self.codec.set(Some(ptr)); ptr } diff --git a/src/shell_parser/braces.rs b/src/shell_parser/braces.rs index c32c5c7d50c3..357c43e1b6a9 100644 --- a/src/shell_parser/braces.rs +++ b/src/shell_parser/braces.rs @@ -476,16 +476,6 @@ pub mod ast { pub(crate) atoms: GroupAtoms, } - impl Default for Group { - fn default() -> Self { - Self { - bubble_up: ptr::null_mut(), - bubble_up_next: None, - atoms: GroupAtoms::Single(Atom::Text(SmolStr::empty())), - } - } - } - pub struct Expansion { // bump-owned mutable slice; raw because expand_nested writes // bubble_up backrefs into elements while recursing through the parent. diff --git a/src/shell_parser/parse.rs b/src/shell_parser/parse.rs index c8b732f6746d..5fed9db09395 100644 --- a/src/shell_parser/parse.rs +++ b/src/shell_parser/parse.rs @@ -342,16 +342,6 @@ pub mod ast { pub else_parts: SmolList, 1>, 1>, } - impl<'arena> Default for If<'arena> { - fn default() -> Self { - Self { - cond: SmolList::zeroes(), - then: SmolList::zeroes(), - else_parts: SmolList::zeroes(), - } - } - } - impl<'arena> If<'arena> { pub(crate) fn to_expr( self, @@ -4330,9 +4320,3 @@ impl Drop for SmolList { } } } - -impl fmt::Display for SmolList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.slice()) - } -} diff --git a/src/spawn/lib.rs b/src/spawn/lib.rs index 38116bd1c5bf..c4ba7de677e7 100644 --- a/src/spawn/lib.rs +++ b/src/spawn/lib.rs @@ -108,11 +108,6 @@ link_impl_ProcessExit! { unreachable!("SyncWindows exit handler is Windows-only"), } } -/// Compat re-export: the `process::spawn_sys` shim module was dissolved into -/// `bun_sys` (LAYERING — moved down so non-spawn callers don't depend on -/// `bun_spawn`). Downstream `runtime/api/bun/*` still spells the old path. -pub use bun_sys as spawn_sys; - #[cfg(unix)] pub use process::{PosixSpawnOptions, PosixSpawnResult, PosixStdio as Stdio, WaitPidResult}; #[cfg(unix)] @@ -239,7 +234,6 @@ pub mod subprocess { pub enum Term { Exited(u32), Signal(u32), - Stopped(u32), Unknown(u32), } diff --git a/src/spawn/process.rs b/src/spawn/process.rs index 94b9059320cd..932a58a8f762 100644 --- a/src/spawn/process.rs +++ b/src/spawn/process.rs @@ -55,12 +55,12 @@ bun_core::declare_scope!(PROCESS, visible); // The raw OS spawn layer (option/result structs, `Rusage`, `spawn_process_posix`) // moved into the leaf `bun_spawn_sys` crate so it has no event-loop dependency. // Re-export here so existing `bun_spawn::process::*` paths keep resolving. -pub use bun_spawn_sys::spawn_process::{IoCounters, WinRusage, WinTimeval, rusage_zeroed}; +pub use bun_spawn_sys::spawn_process::rusage_zeroed; #[cfg(windows)] pub use bun_spawn_sys::uv_getrusage; pub use bun_spawn_sys::{ - Argv, CStrPtr, Dup2, Envp, ExtraPipe, FdT, PidFdType, PidT, PosixSpawnOptions, - PosixSpawnResult, PosixStdio, Rusage, StdioKind, + Argv, CStrPtr, Dup2, Envp, ExtraPipe, PidFdType, PidT, PosixSpawnOptions, PosixSpawnResult, + PosixStdio, Rusage, StdioKind, }; /// Whether the process-exit poll should be registered one-shot. @@ -967,12 +967,6 @@ pub mod waiter_thread_posix { } } - impl Default for NewQueue { - fn default() -> Self { - Self::new() - } - } - /// Intrusive node pushed onto `ConcurrentQueue` from the JS thread and /// drained on the waiter thread. pub struct TaskQueueEntry { diff --git a/src/spawn_sys/Cargo.toml b/src/spawn_sys/Cargo.toml index 5fd858770fc0..dabc8d8cdc33 100644 --- a/src/spawn_sys/Cargo.toml +++ b/src/spawn_sys/Cargo.toml @@ -17,7 +17,7 @@ scopeguard.workspace = true bun_analytics.workspace = true bun_core.workspace = true bun_sys.workspace = true -bun_windows_sys.workspace = true # tier-0 no_std leaf; unconditional like bun_sys/bun_core do — keeps IoCounters alias valid on non-Windows so the flat re-exports at lib.rs:173 and spawn/process.rs:66 stay un-cfg'd +bun_windows_sys.workspace = true # tier-0 no_std leaf; unconditional like bun_sys/bun_core do — keeps the IoCounters alias valid on non-Windows so the flat re-export in lib.rs stays un-cfg'd enumset.workspace = true strum.workspace = true diff --git a/src/sql/mysql/protocol/SSLRequest.rs b/src/sql/mysql/protocol/SSLRequest.rs index f8497254a576..01fd595f711b 100644 --- a/src/sql/mysql/protocol/SSLRequest.rs +++ b/src/sql/mysql/protocol/SSLRequest.rs @@ -18,18 +18,6 @@ pub struct SSLRequest { pub has_connection_attributes: bool, } -impl Default for SSLRequest { - fn default() -> Self { - Self { - capability_flags: Capabilities::default(), - mariadb_capability_flags: MariaDBCapabilities::default(), - max_packet_size: 0xFFFFFF, // 16MB default - character_set: CharacterSet::default(), - has_connection_attributes: false, - } - } -} - impl SSLRequest { pub fn write_internal( &mut self, diff --git a/src/sql_jsc/mysql/JSMySQLConnection.rs b/src/sql_jsc/mysql/JSMySQLConnection.rs index 26cbd93b1360..4e5ed03d3278 100644 --- a/src/sql_jsc/mysql/JSMySQLConnection.rs +++ b/src/sql_jsc/mysql/JSMySQLConnection.rs @@ -458,24 +458,20 @@ impl JSMySQLConnection { else { return Ok(JSValue::ZERO); }; - // Covers `try arguments[7/8].toBunString()` and the null-byte rejection + // Covers `try arguments[8].toBunString()` and the null-byte rejection // below. Ownership passes to `MySQLConnection.init` once `Box::new` // succeeds — we null the locals at that point so the connect-fail path // (which `deref()`s the connection) doesn't double-free. let tls_guard = connection_ctor_args::guard_tls(args.secure, args.tls_config); - let options_str = bun_core::OwnedString::new(arguments[7].to_bun_string(global_object)?); let path_str = bun_core::OwnedString::new(arguments[8].to_bun_string(global_object)?); // `init` takes `Box<[u8]>` per field (each separately owned), so we - // copy each string into its own allocation. `options_buf` becomes an - // empty box. + // copy each string into its own allocation. let username: Box<[u8]> = Box::from(args.username_str.to_utf8_without_ref().slice()); let password: Box<[u8]> = Box::from(args.password_str.to_utf8_without_ref().slice()); let database: Box<[u8]> = Box::from(args.database_str.to_utf8_without_ref().slice()); - let options: Box<[u8]> = Box::from(options_str.to_utf8_without_ref().slice()); let path: Box<[u8]> = Box::from(path_str.to_utf8_without_ref().slice()); - let options_buf: Box<[u8]> = Box::default(); // Reject null bytes in connection parameters to prevent protocol injection // (null bytes act as field terminators in the MySQL wire protocol). @@ -517,8 +513,6 @@ impl JSMySQLConnection { database, username, password, - options, - options_buf, tls_config, secure, args.ssl_mode, diff --git a/src/sql_jsc/mysql/MySQLConnection.rs b/src/sql_jsc/mysql/MySQLConnection.rs index 423bd998bb80..7989d2cf0de7 100644 --- a/src/sql_jsc/mysql/MySQLConnection.rs +++ b/src/sql_jsc/mysql/MySQLConnection.rs @@ -75,16 +75,9 @@ pub struct MySQLConnection { full_auth_requested: bool, auth_data: Vec, - // PERF: database/user/password/options could be sub-slices into options_buf - // (single backing allocation). Only options_buf would need to be - // Box<[u8]>; the others could be ranges into it. Restore the - // single-buffer layout and revert init()'s database/username/password/options - // params from Box<[u8]> back to &[u8] (1 caller-side alloc, not 5). database: Box<[u8]>, user: Box<[u8]>, password: Box<[u8]>, - _options: Box<[u8]>, - options_buf: Box<[u8]>, secure: Option<*mut SslCtx>, tls_config: SSLConfig, tls_status: TLSStatus, @@ -117,8 +110,6 @@ impl Default for MySQLConnection { database: Box::default(), user: Box::default(), password: Box::default(), - _options: Box::default(), - options_buf: Box::default(), secure: None, tls_config: SSLConfig::default(), tls_status: TLSStatus::None, @@ -138,8 +129,6 @@ impl MySQLConnection { database: Box<[u8]>, username: Box<[u8]>, password: Box<[u8]>, - options: Box<[u8]>, - options_buf: Box<[u8]>, tls_config: SSLConfig, secure: Option<*mut SslCtx>, ssl_mode: SSLMode, @@ -149,8 +138,6 @@ impl MySQLConnection { database, user: username, password, - _options: options, - options_buf, socket: Socket::SocketTcp(uws::SocketTCP::detached()), queue: MySQLRequestQueue::init(), statements: PreparedStatementsMap::default(), @@ -321,7 +308,6 @@ impl MySQLConnection { let _read_buffer = core::mem::take(&mut self.read_buffer); let statements = core::mem::take(&mut self.statements); let _tls_config = core::mem::take(&mut self.tls_config); - let _options_buf = core::mem::take(&mut self.options_buf); for stmt in statements.values() { // The map holds an intrusive ref on every cached prepared statement; @@ -338,7 +324,6 @@ impl MySQLConnection { // SAFETY: FFI — secure is an owned SSL_CTX* freed exactly once here unsafe { bun_boringssl_sys::SSL_CTX_free(s) }; } - // _options_buf dropped at scope exit (Box<[u8]> frees via Drop) } pub(crate) fn upgrade_to_tls(&mut self) -> Result<(), FlushQueueError> { diff --git a/src/sql_jsc/mysql/MySQLStatement.rs b/src/sql_jsc/mysql/MySQLStatement.rs index acd9d5be2c2e..f4edeb49bc7d 100644 --- a/src/sql_jsc/mysql/MySQLStatement.rs +++ b/src/sql_jsc/mysql/MySQLStatement.rs @@ -59,12 +59,6 @@ impl MySQLStatement { } } -impl Default for MySQLStatement { - fn default() -> Self { - Self::new(Signature::empty(), Status::Parsing) - } -} - bitflags::bitflags! { #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] diff --git a/src/sql_jsc/shared/SQLDataCell.rs b/src/sql_jsc/shared/SQLDataCell.rs index 6e5b5631ace7..f1c8ce9aceac 100644 --- a/src/sql_jsc/shared/SQLDataCell.rs +++ b/src/sql_jsc/shared/SQLDataCell.rs @@ -144,15 +144,6 @@ pub struct Raw { pub(crate) len: u64, } -impl Default for Raw { - fn default() -> Self { - Self { - ptr: ptr::null(), - len: 0, - } - } -} - #[repr(C)] #[derive(Copy, Clone)] pub struct TypedArray { diff --git a/src/threading/RwLock.rs b/src/threading/RwLock.rs index c2cd34f8e0e1..a0efaeefb781 100644 --- a/src/threading/RwLock.rs +++ b/src/threading/RwLock.rs @@ -120,12 +120,6 @@ unsafe impl Send for RwLock {} // exclusive `&mut T` (requires `T: Send`). `raw` itself is built from atomics. unsafe impl Sync for RwLock {} -impl Default for RwLock { - fn default() -> Self { - Self::new(T::default()) - } -} - impl RwLock { /// Const-init. Parity with `parking_lot::RwLock::new` / /// `parking_lot::const_rwlock`. diff --git a/src/threading/unbounded_queue.rs b/src/threading/unbounded_queue.rs index ef75baa2d433..7ad4a399b7ae 100644 --- a/src/threading/unbounded_queue.rs +++ b/src/threading/unbounded_queue.rs @@ -50,13 +50,6 @@ impl Link { } } -impl Default for Link { - #[inline] - fn default() -> Self { - Self::new() - } -} - /// Shorthand for the common [`Node`] case: `T` embeds a [`Link`] field. /// Implement this and the blanket `impl Node for T` below supplies /// the four accessors. Node types with packed/custom link storage (e.g. diff --git a/test/internal/source-lints/dead-code-escape-limits.json b/test/internal/source-lints/dead-code-escape-limits.json index 408d999e7763..783e05ed6113 100644 --- a/test/internal/source-lints/dead-code-escape-limits.json +++ b/test/internal/source-lints/dead-code-escape-limits.json @@ -7,7 +7,6 @@ "src/collections/multi_array_list.rs": 8, "src/crash_handler/lib.rs": 1, "src/css_derive/lib.rs": 3, - "src/install/PackageInstaller.rs": 3, "src/install/isolated_install/FileCloner.rs": 3, "src/install/lockfile/Package.rs": 1, "src/io/lib.rs": 2, diff --git a/test/js/node/crypto/crypto.test.ts b/test/js/node/crypto/crypto.test.ts index 16b4be3a91a9..4b16765fee5f 100644 --- a/test/js/node/crypto/crypto.test.ts +++ b/test/js/node/crypto/crypto.test.ts @@ -212,6 +212,19 @@ describe("crypto", () => { expect(Hash.hash(input, buf) instanceof Uint8Array).toBe(true); gc(true); }); + + it(`${Hash.name} hash matches the streaming digest and node:crypto`, () => { + const nodeName = Hash.name.toLowerCase().replace("_", "-"); + const expected = crypto.createHash(nodeName).update(input).digest(); + + expect(Hash.hash(input, "hex")).toBe(expected.toString("hex")); + expect(Hash.hash(input, "base64")).toBe(new Hash().update(input).digest("base64")); + + const buf = new Uint8Array(256).fill(0xa5); + expect(Hash.hash(input, buf)).toBe(buf); + expect(Buffer.from(buf.subarray(0, expected.byteLength))).toEqual(expected); + expect(buf.subarray(expected.byteLength).every(byte => byte === 0xa5)).toBe(true); + }); }); } }