From 4a3da5fa881a24ecd85599d4fb714ad56b908000 Mon Sep 17 00:00:00 2001 From: David Herman Date: Wed, 11 Jul 2018 16:50:47 -0700 Subject: [PATCH] `JsBuffer::new()` always produces a zeroed buffer. `JsBuffer::uninitialized()` produces a non-zero-filled buffer but is marked `unsafe`. --- crates/neon-runtime/src/buffer.rs | 7 ++++++- crates/neon-runtime/src/neon.cc | 11 +++++++++++ crates/neon-runtime/src/neon.h | 1 + src/value/binary.rs | 7 ++++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/neon-runtime/src/buffer.rs b/crates/neon-runtime/src/buffer.rs index 71ecf56a2..ede808537 100644 --- a/crates/neon-runtime/src/buffer.rs +++ b/crates/neon-runtime/src/buffer.rs @@ -5,11 +5,16 @@ use std::os::raw::c_void; extern "C" { - /// Mutates the `out` argument provided to refer to a newly created `node::Buffer` object. + /// Mutates the `out` argument provided to refer to a newly created and zero-filled `node::Buffer` object. /// Returns `false` if the value couldn't be created. #[link_name = "Neon_Buffer_New"] pub fn new(out: &mut Local, size: u32) -> bool; + /// Mutates the `out` argument provided to refer to a newly created `node::Buffer` object. + /// Returns `false` if the value couldn't be created. + #[link_name = "Neon_Buffer_Uninitialized"] + pub fn uninitialized(out: &mut Local, size: u32) -> bool; + /// Mutates the `base_out` and `size_out` arguments to access the data of a `node::Buffer` object. #[link_name = "Neon_Buffer_Data"] pub fn data<'a, 'b>(base_out: &'a mut *mut c_void, size_out: &'a mut usize, obj: Local); diff --git a/crates/neon-runtime/src/neon.cc b/crates/neon-runtime/src/neon.cc index e433c3e58..63b2f350d 100644 --- a/crates/neon-runtime/src/neon.cc +++ b/crates/neon-runtime/src/neon.cc @@ -178,6 +178,17 @@ extern "C" bool Neon_Convert_ToObject(v8::Local *out, v8::Local *out, uint32_t size) { + Nan::MaybeLocal maybe = Nan::NewBuffer(size); + if (!maybe.ToLocal(out)) { + return false; + } + + void *data = node::Buffer::Data(*out); + memset(data, 0, size); + return true; +} + +extern "C" bool Neon_Buffer_Uninitialized(v8::Local *out, uint32_t size) { Nan::MaybeLocal maybe = Nan::NewBuffer(size); return maybe.ToLocal(out); } diff --git a/crates/neon-runtime/src/neon.h b/crates/neon-runtime/src/neon.h index f032e9327..f84775b22 100644 --- a/crates/neon-runtime/src/neon.h +++ b/crates/neon-runtime/src/neon.h @@ -53,6 +53,7 @@ extern "C" { void Neon_Buffer_Data(void **base_out, size_t *len_out, v8::Local obj); bool Neon_ArrayBuffer_New(v8::Local *out, v8::Isolate *isolate, uint32_t size); + bool Neon_ArrayBuffer_Uninitialized(v8::Local *out, v8::Isolate *isolate, uint32_t size); void Neon_ArrayBuffer_Data(void **base_out, size_t *len_out, v8::Local buffer); typedef void(*Neon_ChainedScopeCallback)(void *, void *, void *, void *); diff --git a/src/value/binary.rs b/src/value/binary.rs index f76707d7b..72afa4148 100644 --- a/src/value/binary.rs +++ b/src/value/binary.rs @@ -20,11 +20,16 @@ pub struct JsBuffer(raw::Local); impl JsBuffer { - /// Constructs a new `Buffer` object. + /// Constructs a new `Buffer` object, safely zero-filled. pub fn new<'a, C: Context<'a>>(_: &mut C, size: u32) -> JsResult<'a, JsBuffer> { build(|out| { unsafe { neon_runtime::buffer::new(out, size) } }) } + /// Constructs a new `Buffer` object, safely zero-filled. + pub unsafe fn uninitialized<'a, C: Context<'a>>(_: &mut C, size: u32) -> JsResult<'a, JsBuffer> { + build(|out| { neon_runtime::buffer::uninitialized(out, size) }) + } + } impl Managed for JsBuffer {