From 1505d233fd277353f1dba9845360880b74ff3a71 Mon Sep 17 00:00:00 2001 From: mat Date: Fri, 1 Aug 2025 15:46:01 -0900 Subject: [PATCH] fix ub when writing --- fuzz/Cargo.toml | 11 +++++++++-- fuzz/fuzz_targets/borrow_read.rs | 11 +++++++++++ .../fuzz_targets/{fuzz_target_1.rs => owned_write.rs} | 2 +- simdnbt/benches/compare.rs | 3 ++- simdnbt/benches/compare_hypixel.rs | 3 ++- simdnbt/benches/nbt_borrow.rs | 3 ++- simdnbt/benches/nbt_owned.rs | 3 ++- simdnbt/src/fastvec.rs | 9 ++++++--- simdnbt/src/owned/mod.rs | 9 +++++++++ 9 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 fuzz/fuzz_targets/borrow_read.rs rename fuzz/fuzz_targets/{fuzz_target_1.rs => owned_write.rs} (66%) diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7c7132f..925c867 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -12,8 +12,15 @@ libfuzzer-sys = "0.4" simdnbt = { path = "../simdnbt" } [[bin]] -name = "fuzz_target_1" -path = "fuzz_targets/fuzz_target_1.rs" +name = "borrow_read" +path = "fuzz_targets/borrow_read.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "owned_write" +path = "fuzz_targets/owned_write.rs" test = false doc = false bench = false diff --git a/fuzz/fuzz_targets/borrow_read.rs b/fuzz/fuzz_targets/borrow_read.rs new file mode 100644 index 0000000..35b17f3 --- /dev/null +++ b/fuzz/fuzz_targets/borrow_read.rs @@ -0,0 +1,11 @@ +#![no_main] + +use std::io::Cursor; + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + if let Ok(simdnbt::borrow::Nbt::Some(r)) = simdnbt::borrow::read(&mut Cursor::new(data)) { + r.as_compound().to_owned(); + } +}); diff --git a/fuzz/fuzz_targets/fuzz_target_1.rs b/fuzz/fuzz_targets/owned_write.rs similarity index 66% rename from fuzz/fuzz_targets/fuzz_target_1.rs rename to fuzz/fuzz_targets/owned_write.rs index 04670e3..bd999fc 100644 --- a/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/fuzz/fuzz_targets/owned_write.rs @@ -6,6 +6,6 @@ fuzz_target!(|data: &[u8]| { if let Ok(simdnbt::borrow::Nbt::Some(r)) = simdnbt::borrow::read(&mut std::io::Cursor::new(data)) { - r.as_compound().to_owned(); + simdnbt::owned::BaseNbt::write_unnamed(&r.as_compound().to_owned().into(), &mut Vec::new()); } }); diff --git a/simdnbt/benches/compare.rs b/simdnbt/benches/compare.rs index 5971028..555bfc5 100644 --- a/simdnbt/benches/compare.rs +++ b/simdnbt/benches/compare.rs @@ -1,9 +1,10 @@ use std::{ fs::File, + hint::black_box, io::{Cursor, Read}, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput}; +use criterion::{criterion_group, criterion_main, Criterion, Throughput}; use flate2::read::GzDecoder; fn bench_read_file(filename: &str, c: &mut Criterion) { diff --git a/simdnbt/benches/compare_hypixel.rs b/simdnbt/benches/compare_hypixel.rs index 182be42..78fcc4e 100644 --- a/simdnbt/benches/compare_hypixel.rs +++ b/simdnbt/benches/compare_hypixel.rs @@ -1,10 +1,11 @@ use std::{ collections::HashMap, fs::File, + hint::black_box, io::{Cursor, Read}, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput}; +use criterion::{criterion_group, criterion_main, Criterion, Throughput}; use flate2::read::GzDecoder; pub fn bench_read_file(filename: &str, c: &mut Criterion) { diff --git a/simdnbt/benches/nbt_borrow.rs b/simdnbt/benches/nbt_borrow.rs index 9892d8e..bccf0ce 100644 --- a/simdnbt/benches/nbt_borrow.rs +++ b/simdnbt/benches/nbt_borrow.rs @@ -1,9 +1,10 @@ use std::{ fs::File, + hint::black_box, io::{Cursor, Read}, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput}; +use criterion::{criterion_group, criterion_main, Criterion, Throughput}; use flate2::read::GzDecoder; fn bench_file(filename: &str, c: &mut Criterion) { diff --git a/simdnbt/benches/nbt_owned.rs b/simdnbt/benches/nbt_owned.rs index f49d79d..e63dab1 100644 --- a/simdnbt/benches/nbt_owned.rs +++ b/simdnbt/benches/nbt_owned.rs @@ -1,9 +1,10 @@ use std::{ fs::File, + hint::black_box, io::{Cursor, Read}, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput}; +use criterion::{criterion_group, criterion_main, Criterion, Throughput}; use flate2::read::GzDecoder; fn bench_file(filename: &str, c: &mut Criterion) { diff --git a/simdnbt/src/fastvec.rs b/simdnbt/src/fastvec.rs index 4e93413..34a6e21 100644 --- a/simdnbt/src/fastvec.rs +++ b/simdnbt/src/fastvec.rs @@ -271,10 +271,13 @@ impl<'orig, T> FastVecFromVec<'orig, T> { } } impl Drop for FastVecFromVec<'_, T> { + /// Move the FastVec contents back into the original Vec. fn drop(&mut self) { - // we intentionally don't drop the fastvec since the allocation is moved into - // the vec - *self.original = unsafe { ManuallyDrop::take(&mut self.fastvec).into_vec() }; + // we intentionally don't drop anything here + unsafe { + let new_vec = ManuallyDrop::take(&mut self.fastvec).into_vec(); + (self.original as *mut Vec).write(new_vec); + } } } diff --git a/simdnbt/src/owned/mod.rs b/simdnbt/src/owned/mod.rs index 1929974..76e3330 100644 --- a/simdnbt/src/owned/mod.rs +++ b/simdnbt/src/owned/mod.rs @@ -810,4 +810,13 @@ mod tests { assert_ne!(nbt, modified_nbt); } + + #[test] + fn write_compound() { + let nbt = BaseNbt { + name: "".into(), + tag: NbtCompound { values: vec![] }, + }; + BaseNbt::write_unnamed(&nbt, &mut Vec::new()); + } }