commit a87c66f07e06758428c3ce00b317c03daf79753d
parent 4ed1688c9296470b37079807762c47b90a35d0e6
Author: Erich Gubler <erichdongubler@gmail.com>
Date: Thu, 2 Oct 2025 18:09:19 +0000
Bug 1991226 - chore(rust): upgrade `smallvec` 1.14.0 → 1.15.1 r=supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D266740
Diffstat:
8 files changed, 536 insertions(+), 37 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -6322,9 +6322,9 @@ checksum = "75ce4f9dc4a41b4c3476cc925f1efb11b66df373a8fde5d4b8915fa91b5d995e"
[[package]]
name = "smallvec"
-version = "1.13.1"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
dependencies = [
"serde",
]
diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml
@@ -5669,6 +5669,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.9.0 -> 1.10.0"
+[[audits.smallvec]]
+who = "Erich Gubler <erichdongubler@gmail.com>"
+criteria = "safe-to-deploy"
+delta = "1.14.0 -> 1.15.1"
+
[[audits.smart-default]]
who = "Gabriele Svelto <gsvelto@mozilla.com>"
criteria = "safe-to-deploy"
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
@@ -664,13 +664,6 @@ user-id = 3618
user-login = "dtolnay"
user-name = "David Tolnay"
-[[publisher.smallvec]]
-version = "1.13.1"
-when = "2024-01-19"
-user-id = 2017
-user-login = "mbrubeck"
-user-name = "Matt Brubeck"
-
[[publisher.syn]]
version = "2.0.106"
when = "2025-08-16"
@@ -2380,6 +2373,26 @@ and there were no hits.
'''
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
+[[audits.google.audits.smallvec]]
+who = "Manish Goregaokar <manishearth@google.com>"
+criteria = "safe-to-deploy"
+version = "1.13.2"
+aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
+
+[[audits.google.audits.smallvec]]
+who = "Jonathan Hao <phao@chromium.org>"
+criteria = "safe-to-deploy"
+delta = "1.13.2 -> 1.14.0"
+notes = """
+WARNING: This certification is a result of a **partial** audit. The
+`malloc_size_of` feature has **not** been audited. This feature does
+not explicitly document its safety requirements.
+See also https://chromium-review.googlesource.com/c/chromium/src/+/6275133/comment/ea0d7a93_98051a2e/
+and https://github.com/servo/malloc_size_of/issues/8.
+This feature is banned in gnrt_config.toml.
+"""
+aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
+
[[audits.google.audits.socket2]]
who = "David Koloski <dkoloski@google.com>"
criteria = "safe-to-deploy"
diff --git a/third_party/rust/smallvec/.cargo-checksum.json b/third_party/rust/smallvec/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"668bb964a243127d65605bb7a0d8d3c81bcbd8f7656a5b5734766ef534b4abcb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"d82015eae942ee5cf74ace8c3c260ee2c6b5bcbeeb87254d2c72622c747a708a","debug_metadata/README.md":"4d7f1c1b2c25ce2231ef71864d06e54323867459035b53bc9e00f66a0a44f82e","debug_metadata/smallvec.natvis":"3092ddebd8fffc3486536d7f27f8c5eae3a8a093d45cd8eeb3946ea2b0c35a15","scripts/run_miri.sh":"74a9f9adc43f986e81977b03846f7dd00122a0150bd8ec3fe4842a1a787e0f07","src/arbitrary.rs":"22e55cfbf60374945b30e6d0855129eff67cd8b878cef6fa997e1f4be67b9e3d","src/lib.rs":"25fe85b6ae7b3972211bf57aeded4c7b72c47e4d843c7a4ba66908442197b5a0","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"29c6e5dad62ebfea74e5116ac4a344b127b91cfb769fe9ba8b02b53773cf7ec8","tests/debugger_visualizer.rs":"185456ad253957fc0c9e904ff8a1135397ac991c29fa3c60f75d8d81f7463022","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"}
-\ No newline at end of file
+{"files":{"Cargo.lock":"bc6c5ff08e0ba6534eb5490aca5b2c7a0b09b141127f8405734c1aa975cb8a25","Cargo.toml":"23b775d343d15c7c212134c69a791d75fcdfb4527224b20daf401b494dd4f0c9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"d82015eae942ee5cf74ace8c3c260ee2c6b5bcbeeb87254d2c72622c747a708a","debug_metadata/README.md":"4d7f1c1b2c25ce2231ef71864d06e54323867459035b53bc9e00f66a0a44f82e","debug_metadata/smallvec.natvis":"3092ddebd8fffc3486536d7f27f8c5eae3a8a093d45cd8eeb3946ea2b0c35a15","scripts/run_miri.sh":"74a9f9adc43f986e81977b03846f7dd00122a0150bd8ec3fe4842a1a787e0f07","src/arbitrary.rs":"22e55cfbf60374945b30e6d0855129eff67cd8b878cef6fa997e1f4be67b9e3d","src/lib.rs":"881e5b2c9afecd0091df0d1232fd557edbb9d58304d073356b066728af14ab2e","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"77d7dac593a3d4228b99de547fb81de8c451da5fe4f409c48670c6d463ef6f49","tests/debugger_visualizer.rs":"185456ad253957fc0c9e904ff8a1135397ac991c29fa3c60f75d8d81f7463022","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"}
+\ No newline at end of file
diff --git a/third_party/rust/smallvec/Cargo.lock b/third_party/rust/smallvec/Cargo.lock
@@ -0,0 +1,198 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
+
+[[package]]
+name = "arbitrary"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bincode"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740"
+dependencies = [
+ "unty",
+]
+
+[[package]]
+name = "debugger_test"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d95bb55f592fbb86947bee426d831de84bd65602a54f5cdcb10bfa70a62e52a0"
+dependencies = [
+ "anyhow",
+ "log",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "debugger_test_parser"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebe536452a777752b9316f0c840afbb94a2411684d4f15c081449ea801ef9e75"
+dependencies = [
+ "anyhow",
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "log"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+
+[[package]]
+name = "malloc_size_of"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d719de8b8f230028cf8192ae4c1b25267cd6b8a99d2747d345a70b8c81aa13"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+dependencies = [
+ "arbitrary",
+ "bincode 1.3.3",
+ "bincode 2.0.1",
+ "debugger_test",
+ "debugger_test_parser",
+ "malloc_size_of",
+ "serde",
+ "unty",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "unty"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
diff --git a/third_party/rust/smallvec/Cargo.toml b/third_party/rust/smallvec/Cargo.toml
@@ -12,8 +12,14 @@
[package]
edition = "2018"
name = "smallvec"
-version = "1.13.1"
+version = "1.15.1"
authors = ["The Servo Project Developers"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
description = "'Small vector' optimization: store up to a small number of items on the stack"
documentation = "https://docs.rs/smallvec/"
readme = "README.md"
@@ -36,37 +42,69 @@ rustdoc-args = [
"--generate-link-to-definition",
]
+[features]
+const_generics = []
+const_new = ["const_generics"]
+debugger_visualizer = []
+drain_filter = []
+drain_keep_rest = ["drain_filter"]
+impl_bincode = [
+ "bincode",
+ "unty",
+]
+may_dangle = []
+specialization = []
+union = []
+write = []
+
+[lib]
+name = "smallvec"
+path = "src/lib.rs"
+
[[test]]
name = "debugger_visualizer"
path = "tests/debugger_visualizer.rs"
test = false
required-features = ["debugger_visualizer"]
+[[test]]
+name = "macro"
+path = "tests/macro.rs"
+
+[[bench]]
+name = "bench"
+path = "benches/bench.rs"
+
[dependencies.arbitrary]
version = "1"
optional = true
+[dependencies.bincode]
+version = "2"
+optional = true
+default-features = false
+
+[dependencies.malloc_size_of]
+version = "0.1"
+optional = true
+default-features = false
+
[dependencies.serde]
version = "1"
optional = true
default-features = false
-[dev-dependencies.bincode]
+[dependencies.unty]
+version = "0.0.4"
+optional = true
+default-features = false
+
+[dev-dependencies.bincode1]
version = "1.0.1"
+package = "bincode"
[dev-dependencies.debugger_test]
version = "0.1.0"
[dev-dependencies.debugger_test_parser]
version = "0.1.0"
-
-[features]
-const_generics = []
-const_new = ["const_generics"]
-debugger_visualizer = []
-drain_filter = []
-drain_keep_rest = ["drain_filter"]
-may_dangle = []
-specialization = []
-union = []
-write = []
diff --git a/third_party/rust/smallvec/src/lib.rs b/third_party/rust/smallvec/src/lib.rs
@@ -126,6 +126,9 @@ use core::ops::{self, Range, RangeBounds};
use core::ptr::{self, NonNull};
use core::slice::{self, SliceIndex};
+#[cfg(feature = "malloc_size_of")]
+use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
+
#[cfg(feature = "serde")]
use serde::{
de::{Deserialize, Deserializer, SeqAccess, Visitor},
@@ -177,23 +180,24 @@ use core::mem::ManuallyDrop;
/// example, `smallvec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
-
#[macro_export]
macro_rules! smallvec {
// count helper: transform any expression into 1
(@one $x:expr) => (1usize);
+ () => (
+ $crate::SmallVec::new()
+ );
($elem:expr; $n:expr) => ({
$crate::SmallVec::from_elem($elem, $n)
});
- ($($x:expr),*$(,)*) => ({
- let count = 0usize $(+ $crate::smallvec!(@one $x))*;
- #[allow(unused_mut)]
+ ($($x:expr),+$(,)?) => ({
+ let count = 0usize $(+ $crate::smallvec!(@one $x))+;
let mut vec = $crate::SmallVec::new();
if count <= vec.inline_size() {
$(vec.push($x);)*
vec
} else {
- $crate::SmallVec::from_vec($crate::alloc::vec![$($x,)*])
+ $crate::SmallVec::from_vec($crate::alloc::vec![$($x,)+])
}
});
}
@@ -1372,13 +1376,14 @@ impl<A: Array> SmallVec<A> {
}
let mut ptr = ptr.as_ptr();
let len = *len_ptr;
+ if index > len {
+ panic!("index exceeds length");
+ }
+ // SAFETY: add is UB if index > len, but we panicked first
ptr = ptr.add(index);
if index < len {
+ // Shift element to the right of `index`.
ptr::copy(ptr, ptr.add(1), len - index);
- } else if index == len {
- // No elements need shifting.
- } else {
- panic!("index exceeds length");
}
*len_ptr = len + 1;
ptr::write(ptr, element);
@@ -1532,7 +1537,7 @@ impl<A: Array> SmallVec<A> {
/// Retains only the elements specified by the predicate.
///
/// This method is identical in behaviour to [`retain`]; it is included only
- /// to maintain api-compatability with `std::Vec`, where the methods are
+ /// to maintain api-compatibility with `std::Vec`, where the methods are
/// separate for historical reasons.
pub fn retain_mut<F: FnMut(&mut A::Item) -> bool>(&mut self, f: F) {
self.retain(f)
@@ -1970,6 +1975,32 @@ where
}
}
+#[cfg(feature = "malloc_size_of")]
+impl<A: Array> MallocShallowSizeOf for SmallVec<A> {
+ fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
+ if self.spilled() {
+ unsafe { ops.malloc_size_of(self.as_ptr()) }
+ } else {
+ 0
+ }
+ }
+}
+
+#[cfg(feature = "malloc_size_of")]
+impl<A> MallocSizeOf for SmallVec<A>
+where
+ A: Array,
+ A::Item: MallocSizeOf,
+{
+ fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
+ let mut n = self.shallow_size_of(ops);
+ for elem in self.iter() {
+ n += elem.size_of(ops);
+ }
+ n
+ }
+}
+
#[cfg(feature = "specialization")]
trait SpecFrom<A: Array, S> {
fn spec_from(slice: S) -> SmallVec<A>;
@@ -2469,3 +2500,106 @@ impl<T> Clone for ConstNonNull<T> {
}
impl<T> Copy for ConstNonNull<T> {}
+
+#[cfg(feature = "impl_bincode")]
+use bincode::{
+ de::{BorrowDecoder, Decode, Decoder, read::Reader},
+ enc::{Encode, Encoder, write::Writer},
+ error::{DecodeError, EncodeError},
+ BorrowDecode,
+};
+
+#[cfg(feature = "impl_bincode")]
+impl<A, Context> Decode<Context> for SmallVec<A>
+where
+ A: Array,
+ A::Item: Decode<Context>,
+{
+ fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
+ use core::convert::TryInto;
+ let len = u64::decode(decoder)?;
+ let len = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
+ decoder.claim_container_read::<A::Item>(len)?;
+
+ let mut vec = SmallVec::with_capacity(len);
+ if unty::type_equal::<A::Item, u8>() {
+ // Initialize the smallvec's buffer. Note that we need to do this through
+ // the raw pointer as we cannot name the type [u8; N] even though A::Item is u8.
+ let ptr = vec.as_mut_ptr();
+ // SAFETY: A::Item is u8 and the smallvec has been allocated with enough capacity
+ unsafe {
+ core::ptr::write_bytes(ptr, 0, len);
+ vec.set_len(len);
+ }
+ // Read the data into the smallvec's buffer.
+ let slice = vec.as_mut_slice();
+ // SAFETY: A::Item is u8
+ let slice = unsafe { core::mem::transmute::<&mut [A::Item], &mut [u8]>(slice) };
+ decoder.reader().read(slice)?;
+ } else {
+ for _ in 0..len {
+ decoder.unclaim_bytes_read(core::mem::size_of::<A::Item>());
+ vec.push(A::Item::decode(decoder)?);
+ }
+ }
+ Ok(vec)
+ }
+}
+
+#[cfg(feature = "impl_bincode")]
+impl<'de, A, Context> BorrowDecode<'de, Context> for SmallVec<A>
+where
+ A: Array,
+ A::Item: BorrowDecode<'de, Context>,
+{
+ fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
+ use core::convert::TryInto;
+ let len = u64::decode(decoder)?;
+ let len = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
+ decoder.claim_container_read::<A::Item>(len)?;
+
+ let mut vec = SmallVec::with_capacity(len);
+ if unty::type_equal::<A::Item, u8>() {
+ // Initialize the smallvec's buffer. Note that we need to do this through
+ // the raw pointer as we cannot name the type [u8; N] even though A::Item is u8.
+ let ptr = vec.as_mut_ptr();
+ // SAFETY: A::Item is u8 and the smallvec has been allocated with enough capacity
+ unsafe {
+ core::ptr::write_bytes(ptr, 0, len);
+ vec.set_len(len);
+ }
+ // Read the data into the smallvec's buffer.
+ let slice = vec.as_mut_slice();
+ // SAFETY: A::Item is u8
+ let slice = unsafe { core::mem::transmute::<&mut [A::Item], &mut [u8]>(slice) };
+ decoder.reader().read(slice)?;
+ } else {
+ for _ in 0..len {
+ decoder.unclaim_bytes_read(core::mem::size_of::<A::Item>());
+ vec.push(A::Item::borrow_decode(decoder)?);
+ }
+ }
+ Ok(vec)
+ }
+}
+
+#[cfg(feature = "impl_bincode")]
+impl<A> Encode for SmallVec<A>
+where
+ A: Array,
+ A::Item: Encode,
+{
+ fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
+ (self.len() as u64).encode(encoder)?;
+ if unty::type_equal::<A::Item, u8>() {
+ // Safety: A::Item is u8
+ let slice: &[u8] = unsafe { core::mem::transmute(self.as_slice()) };
+ encoder.writer().write(slice)?;
+ } else {
+ for item in self.iter() {
+ item.encode(encoder)?;
+ }
+ }
+ Ok(())
+ }
+}
diff --git a/third_party/rust/smallvec/src/tests.rs b/third_party/rust/smallvec/src/tests.rs
@@ -752,7 +752,7 @@ fn test_from_vec() {
#[test]
fn test_retain() {
- // Test inline data storate
+ // Test inline data storage
let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
sv.retain(|&mut i| i != 3);
assert_eq!(sv.pop(), Some(4));
@@ -835,7 +835,7 @@ fn test_write() {
#[cfg(feature = "serde")]
#[test]
fn test_serde() {
- use bincode::{config, deserialize};
+ use bincode1::{config, deserialize};
let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
small_vec.push(1);
let encoded = config().limit(100).serialize(&small_vec).unwrap();
@@ -996,7 +996,23 @@ fn test_clone_from() {
#[test]
fn test_size() {
use core::mem::size_of;
- assert_eq!(24, size_of::<SmallVec<[u8; 8]>>());
+ const PTR_SIZE: usize = size_of::<usize>();
+ #[cfg(feature = "union")]
+ {
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; 0]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; 1]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; PTR_SIZE]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; PTR_SIZE + 1]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; 2 * PTR_SIZE]>>());
+ assert_eq!(4 * PTR_SIZE, size_of::<SmallVec<[u8; 2 * PTR_SIZE + 1]>>());
+ }
+ #[cfg(not(feature = "union"))]
+ {
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; 0]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; 1]>>());
+ assert_eq!(3 * PTR_SIZE, size_of::<SmallVec<[u8; PTR_SIZE]>>());
+ assert_eq!(4 * PTR_SIZE, size_of::<SmallVec<[u8; PTR_SIZE + 1]>>());
+ }
}
#[cfg(feature = "drain_filter")]
@@ -1023,3 +1039,98 @@ fn drain_keep_rest() {
assert_eq!(a, SmallVec::<[i32; 3]>::from_slice(&[1i32, 3, 5, 6, 7, 8]));
}
+
+/// This assortment of tests, in combination with miri, verifies we handle UB on fishy arguments
+/// given to SmallVec. Draining and extending the allocation are fairly well-tested earlier, but
+/// `smallvec.insert(usize::MAX, val)` once slipped by!
+///
+/// All code that indexes into SmallVecs should be tested with such "trivially wrong" args.
+#[test]
+fn max_dont_panic() {
+ let mut sv: SmallVec<[i32; 2]> = smallvec![0];
+ let _ = sv.get(usize::MAX);
+ sv.truncate(usize::MAX);
+}
+
+#[test]
+#[should_panic]
+fn max_remove() {
+ let mut sv: SmallVec<[i32; 2]> = smallvec![0];
+ sv.remove(usize::MAX);
+}
+
+#[test]
+#[should_panic]
+fn max_swap_remove() {
+ let mut sv: SmallVec<[i32; 2]> = smallvec![0];
+ sv.swap_remove(usize::MAX);
+}
+
+#[test]
+#[should_panic]
+fn test_insert_out_of_bounds() {
+ let mut v: SmallVec<[i32; 4]> = SmallVec::new();
+ v.insert(10, 6);
+}
+
+#[cfg(feature = "impl_bincode")]
+#[test]
+fn test_bincode() {
+ let config = bincode::config::standard();
+ let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
+ let mut buffer = [0u8; 128];
+ small_vec.push(1);
+ let bytes_written = bincode::encode_into_slice(&small_vec, &mut buffer, config).unwrap();
+ let (decoded, bytes_read) =
+ bincode::decode_from_slice::<SmallVec<[i32; 2]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ let (decoded, bytes_read) =
+ bincode::borrow_decode_from_slice::<SmallVec<[i32; 2]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ // Spill the vec
+ small_vec.push(2);
+ small_vec.push(3);
+ small_vec.push(4);
+ // Check again after spilling.
+ let bytes_written = bincode::encode_into_slice(&small_vec, &mut buffer, config).unwrap();
+ let (decoded, bytes_read) =
+ bincode::decode_from_slice::<SmallVec<[i32; 2]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ let (decoded, bytes_read) =
+ bincode::borrow_decode_from_slice::<SmallVec<[i32; 2]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+}
+
+#[cfg(feature = "impl_bincode")]
+#[test]
+fn test_bincode_u8() {
+ let config = bincode::config::standard();
+ let mut small_vec: SmallVec<[u8; 16]> = SmallVec::new();
+ let mut buffer = [0u8; 128];
+ small_vec.extend_from_slice(b"testing test");
+ let bytes_written = bincode::encode_into_slice(&small_vec, &mut buffer, config).unwrap();
+ let (decoded, bytes_read) =
+ bincode::decode_from_slice::<SmallVec<[u8; 16]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ let (decoded, bytes_read) =
+ bincode::borrow_decode_from_slice::<SmallVec<[u8; 16]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ // Spill the vec
+ small_vec.extend_from_slice(b"some more testing");
+ // Check again after spilling.
+ let bytes_written = bincode::encode_into_slice(&small_vec, &mut buffer, config).unwrap();
+ let (decoded, bytes_read) =
+ bincode::decode_from_slice::<SmallVec<[u8; 16]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+ let (decoded, bytes_read) =
+ bincode::borrow_decode_from_slice::<SmallVec<[u8; 16]>, _>(&buffer, config).unwrap();
+ assert_eq!(bytes_written, bytes_read);
+ assert_eq!(small_vec, decoded);
+}