Skip to content

Unsound unsafe usages #15020

@Nugine

Description

@Nugine

clippy::mut_from_ref

deno/core/ops_metrics.rs

Lines 56 to 62 in 4e92f38

#[allow(clippy::mut_from_ref)]
#[inline]
fn ops_mut(&self) -> &mut Vec<OpMetrics> {
// SAFETY: `OpsTracker` is created after registering ops so it is guaranteed
// that that `ops` will be initialized.
unsafe { &mut *self.ops.get() }
}

It is not safe to create &mut [u8] which is pointing to uninitialized memory.
See also rust-lang/unsafe-code-guidelines#71

deno/ext/net/ops_tls.rs

Lines 378 to 382 in 4e92f38

// TODO(bartlomieju):
#[allow(clippy::undocumented_unsafe_blocks)]
let buf_slice =
unsafe { &mut *(buf.unfilled_mut() as *mut [_] as *mut [u8]) };
let bytes_read = self.tls.reader().read(buf_slice)?;

deno/serde_v8/de.rs

Lines 679 to 692 in 4e92f38

let mut buf = Vec::with_capacity(capacity);
let mut nchars = 0;
let data = buf.as_mut_ptr();
let length = s.write_utf8(
scope,
// SAFETY: we're essentially providing the raw internal slice/buffer owned by the Vec
// which fulfills all of from_raw_parts_mut's safety requirements besides "initialization"
// and since we're operating on a [u8] not [T] we can safely assume the slice's values
// are sufficiently "initialized" for writes
unsafe { std::slice::from_raw_parts_mut(data, capacity) },
Some(&mut nchars),
v8::WriteOptions::NO_NULL_TERMINATION
| v8::WriteOptions::REPLACE_INVALID_UTF8,
);

deno/serde_v8/de.rs

Lines 708 to 720 in 4e92f38

let mut buf = Vec::with_capacity(capacity);
let data = buf.as_mut_ptr();
let length = s.write_utf8(
scope,
// SAFETY: we're essentially providing the raw internal slice/buffer owned by the Vec
// which fulfills all of from_raw_parts_mut's safety requirements besides "initialization"
// and since we're operating on a [u8] not [T] we can safely assume the slice's values
// are sufficiently "initialized" for writes
unsafe { std::slice::from_raw_parts_mut(data, capacity) },
None,
v8::WriteOptions::NO_NULL_TERMINATION
| v8::WriteOptions::REPLACE_INVALID_UTF8,
);

clippy::uninit_vec

let len = v8str.length();
let mut buffer = SmallVec::with_capacity(len);
// SAFETY: we set length == capacity (see previous line),
// before immediately writing into that buffer and sanity check with an assert
#[allow(clippy::uninit_vec)]
unsafe {
buffer.set_len(len);
let written = v8str.write_one_byte(
scope,
&mut buffer,
0,
v8::WriteOptions::NO_NULL_TERMINATION,
);
assert!(written == len);
}

let len = v8str.length();
let mut buffer = Vec::with_capacity(len);
// SAFETY: we set length == capacity (see previous line),
// before immediately writing into that buffer and sanity check with an assert
#[allow(clippy::uninit_vec)]
unsafe {
buffer.set_len(len);
let written = v8str.write(
scope,
&mut buffer,
0,
v8::WriteOptions::NO_NULL_TERMINATION,
);
assert!(written == len);
}

deno/snapshots/lib.rs

Lines 30 to 53 in 4e92f38

static CLI_SNAPSHOT: Lazy<Box<[u8]>> = Lazy::new(
#[allow(clippy::uninit_vec)]
#[cold]
#[inline(never)]
|| {
static COMPRESSED_CLI_SNAPSHOT: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/CLI_SNAPSHOT.bin"));
let size =
u32::from_le_bytes(COMPRESSED_CLI_SNAPSHOT[0..4].try_into().unwrap())
as usize;
let mut vec = Vec::with_capacity(size);
// SAFETY: vec is allocated with exact snapshot size (+ alignment)
// SAFETY: non zeroed bytes are overwritten with decompressed snapshot
unsafe {
vec.set_len(size);
}
lzzzz::lz4::decompress(&COMPRESSED_CLI_SNAPSHOT[4..], &mut vec).unwrap();
vec.into_boxed_slice()
},
);

What is this?

impl ToV8 for Value<'_> {
fn to_v8<'a>(
&self,
_scope: &mut v8::HandleScope<'a>,
) -> Result<v8::Local<'a, v8::Value>, crate::Error> {
// SAFETY: not fully safe, since lifetimes are detached from original scope
Ok(unsafe { transmute(self.v8_value) })
}
}
impl FromV8 for Value<'_> {
fn from_v8(
_scope: &mut v8::HandleScope,
value: v8::Local<v8::Value>,
) -> Result<Self, crate::Error> {
// SAFETY: not fully safe, since lifetimes are detached from original scope
Ok(unsafe { transmute::<Value, Value>(value.into()) })
}
}

Related (maybe):

Metadata

Metadata

Assignees

No one assigned

    Labels

    featnew feature (which has been agreed to/accepted)

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions