Skip to content

Commit

Permalink
[HACK] temporary FastApiTypedArray fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
targos authored and nodejs-github-bot committed Dec 3, 2024
1 parent 50087cf commit d1bffa9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 114 deletions.
27 changes: 1 addition & 26 deletions src/crypto/crypto_timing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
namespace node {

using v8::FastApiCallbackOptions;
using v8::FastApiTypedArray;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Local;
Expand Down Expand Up @@ -50,35 +49,11 @@ void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.size()) == 0);
}

bool FastTimingSafeEqual(Local<Value> receiver,
const FastApiTypedArray<uint8_t>& a,
const FastApiTypedArray<uint8_t>& b,
// NOLINTNEXTLINE(runtime/references)
FastApiCallbackOptions& options) {
uint8_t* data_a;
uint8_t* data_b;
if (a.length() != b.length() || !a.getStorageIfAligned(&data_a) ||
!b.getStorageIfAligned(&data_b)) {
TRACK_V8_FAST_API_CALL("crypto.timingSafeEqual.error");
HandleScope scope(options.isolate);
THROW_ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH(options.isolate);
return false;
}

TRACK_V8_FAST_API_CALL("crypto.timingSafeEqual.ok");
return CRYPTO_memcmp(data_a, data_b, a.length()) == 0;
}

static v8::CFunction fast_equal(v8::CFunction::Make(FastTimingSafeEqual));

void Initialize(Environment* env, Local<Object> target) {
SetFastMethodNoSideEffect(
env->context(), target, "timingSafeEqual", TimingSafeEqual, &fast_equal);
SetMethod(env->context(), target, "timingSafeEqual", TimingSafeEqual);
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(TimingSafeEqual);
registry->Register(FastTimingSafeEqual);
registry->Register(fast_equal.GetTypeInfo());
}
} // namespace Timing

Expand Down
99 changes: 34 additions & 65 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,15 @@
#include "nbytes.h"

#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \
THROW_AND_RETURN_IF_NOT_BUFFER(env, obj, "argument") \
THROW_AND_RETURN_IF_NOT_BUFFER(env, obj, "argument")

#define THROW_AND_RETURN_VAL_UNLESS_BUFFER(isolate, val, prefix, retval) \
do { \
if (!Buffer::HasInstance(val)) { \
node::THROW_ERR_INVALID_ARG_TYPE(isolate, prefix " must be a buffer"); \
return retval; \
} \
} while (0)

#define THROW_AND_RETURN_IF_OOB(r) \
do { \
Expand All @@ -60,7 +68,6 @@ using v8::ArrayBufferView;
using v8::BackingStore;
using v8::Context;
using v8::EscapableHandleScope;
using v8::FastApiTypedArray;
using v8::FunctionCallbackInfo;
using v8::Global;
using v8::HandleScope;
Expand Down Expand Up @@ -582,19 +589,17 @@ void SlowCopy(const FunctionCallbackInfo<Value>& args) {

// Assume caller has properly validated args.
uint32_t FastCopy(Local<Value> receiver,
const v8::FastApiTypedArray<uint8_t>& source,
const v8::FastApiTypedArray<uint8_t>& target,
Local<Value> source_obj,
Local<Value> target_obj,
uint32_t target_start,
uint32_t source_start,
uint32_t to_copy) {
uint8_t* source_data;
CHECK(source.getStorageIfAligned(&source_data));

uint8_t* target_data;
CHECK(target.getStorageIfAligned(&target_data));

memmove(target_data + target_start, source_data + source_start, to_copy);
uint32_t to_copy,
// NOLINTNEXTLINE(runtime/references) This is V8 api.
v8::FastApiCallbackOptions& options) {
ArrayBufferViewContents<char> source(source_obj);
SPREAD_BUFFER_ARG(target_obj, target);

memmove(target_data + target_start, source.data() + source_start, to_copy);
return to_copy;
}

Expand Down Expand Up @@ -857,24 +862,6 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
args.GetReturnValue().Set(val);
}

int32_t FastCompare(v8::Local<v8::Value>,
const FastApiTypedArray<uint8_t>& a,
const FastApiTypedArray<uint8_t>& b) {
uint8_t* data_a;
uint8_t* data_b;
CHECK(a.getStorageIfAligned(&data_a));
CHECK(b.getStorageIfAligned(&data_b));

size_t cmp_length = std::min(a.length(), b.length());

return normalizeCompareVal(
cmp_length > 0 ? memcmp(data_a, data_b, cmp_length) : 0,
a.length(),
b.length());
}

static v8::CFunction fast_compare(v8::CFunction::Make(FastCompare));

// Computes the offset for starting an indexOf or lastIndexOf search.
// Returns either a valid offset in [0...<length - 1>], ie inside the Buffer,
// or -1 to signal that there is no possible match.
Expand Down Expand Up @@ -1125,7 +1112,7 @@ int32_t IndexOfNumber(const uint8_t* buffer_data,
return ptr != nullptr ? static_cast<int32_t>(ptr_uint8 - buffer_data) : -1;
}

void SlowIndexOfNumber(const FunctionCallbackInfo<Value>& args) {
void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
CHECK(args[1]->IsUint32());
CHECK(args[2]->IsNumber());
CHECK(args[3]->IsBoolean());
Expand All @@ -1141,20 +1128,6 @@ void SlowIndexOfNumber(const FunctionCallbackInfo<Value>& args) {
buffer.data(), buffer.length(), needle, offset_i64, is_forward));
}

int32_t FastIndexOfNumber(v8::Local<v8::Value>,
const FastApiTypedArray<uint8_t>& buffer,
uint32_t needle,
int64_t offset_i64,
bool is_forward) {
uint8_t* buffer_data;
CHECK(buffer.getStorageIfAligned(&buffer_data));
return IndexOfNumber(
buffer_data, buffer.length(), needle, offset_i64, is_forward);
}

static v8::CFunction fast_index_of_number(
v8::CFunction::Make(FastIndexOfNumber));

void Swap16(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
Expand Down Expand Up @@ -1502,21 +1475,25 @@ void SlowWriteString(const FunctionCallbackInfo<Value>& args) {

template <encoding encoding>
uint32_t FastWriteString(Local<Value> receiver,
const v8::FastApiTypedArray<uint8_t>& dst,
Local<Value> dst,
const v8::FastOneByteString& src,
uint32_t offset,
uint32_t max_length) {
uint8_t* dst_data;
CHECK(dst.getStorageIfAligned(&dst_data));
CHECK(offset <= dst.length());
CHECK(dst.length() - offset <= std::numeric_limits<uint32_t>::max());
uint32_t max_length,
// NOLINTNEXTLINE(runtime/references) This is V8 api.
v8::FastApiCallbackOptions& options) {
THROW_AND_RETURN_VAL_UNLESS_BUFFER(options.isolate, dst, "dst", 0);
SPREAD_BUFFER_ARG(dst, dst_buffer);
CHECK(dst_buffer_length <=
static_cast<size_t>(std::numeric_limits<uint32_t>::max()));
uint32_t dst_size = static_cast<uint32_t>(dst_buffer_length);
CHECK(offset <= dst_size);
TRACK_V8_FAST_API_CALL("buffer.writeString");

return WriteOneByteString<encoding>(
src.data,
src.length,
reinterpret_cast<char*>(dst_data + offset),
std::min<uint32_t>(dst.length() - offset, max_length));
reinterpret_cast<char*>(dst_buffer_data + offset),
std::min<uint32_t>(dst_size - offset, max_length));
}

static v8::CFunction fast_write_string_ascii(
Expand All @@ -1543,16 +1520,12 @@ void Initialize(Local<Object> target,
"byteLengthUtf8",
SlowByteLengthUtf8,
&fast_byte_length_utf8);
SetFastMethod(context, target, "copy", SlowCopy, &fast_copy);
SetFastMethodNoSideEffect(context, target, "compare", Compare, &fast_compare);
SetMethod(context, target, "copy", SlowCopy);
SetMethod(context, target, "compare", Compare);
SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset);
SetMethod(context, target, "fill", Fill);
SetMethodNoSideEffect(context, target, "indexOfBuffer", IndexOfBuffer);
SetFastMethodNoSideEffect(context,
target,
"indexOfNumber",
SlowIndexOfNumber,
&fast_index_of_number);
SetMethodNoSideEffect(context, target, "indexOfNumber", IndexOfNumber);
SetMethodNoSideEffect(context, target, "indexOfString", IndexOfString);

SetMethod(context, target, "detachArrayBuffer", DetachArrayBuffer);
Expand Down Expand Up @@ -1622,14 +1595,10 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(fast_copy.GetTypeInfo());
registry->Register(FastCopy);
registry->Register(Compare);
registry->Register(FastCompare);
registry->Register(fast_compare.GetTypeInfo());
registry->Register(CompareOffset);
registry->Register(Fill);
registry->Register(IndexOfBuffer);
registry->Register(SlowIndexOfNumber);
registry->Register(FastIndexOfNumber);
registry->Register(fast_index_of_number.GetTypeInfo());
registry->Register(IndexOfNumber);
registry->Register(IndexOfString);

registry->Register(Swap16);
Expand Down
30 changes: 7 additions & 23 deletions src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,6 @@ using CFunctionCallbackWithStrings =
bool (*)(v8::Local<v8::Value>,
const v8::FastOneByteString& input,
const v8::FastOneByteString& base);
using CFunctionCallbackWithTwoUint8Arrays =
int32_t (*)(v8::Local<v8::Value>,
const v8::FastApiTypedArray<uint8_t>&,
const v8::FastApiTypedArray<uint8_t>&);
using CFunctionCallbackWithTwoUint8ArraysFallback =
bool (*)(v8::Local<v8::Value>,
const v8::FastApiTypedArray<uint8_t>&,
const v8::FastApiTypedArray<uint8_t>&,
v8::FastApiCallbackOptions&);
using CFunctionCallbackWithUint8ArrayUint32Int64Bool =
int32_t (*)(v8::Local<v8::Value>,
const v8::FastApiTypedArray<uint8_t>&,
uint32_t,
int64_t,
bool);
using CFunctionWithUint32 = uint32_t (*)(v8::Local<v8::Value>,
const uint32_t input);
using CFunctionWithDoubleReturnDouble = double (*)(v8::Local<v8::Value>,
Expand All @@ -68,18 +53,20 @@ using CFunctionWithBool = void (*)(v8::Local<v8::Value>,

using CFunctionWriteString =
uint32_t (*)(v8::Local<v8::Value> receiver,
const v8::FastApiTypedArray<uint8_t>& dst,
v8::Local<v8::Value> dst,
const v8::FastOneByteString& src,
uint32_t offset,
uint32_t max_length);
uint32_t max_length,
v8::FastApiCallbackOptions&);

using CFunctionBufferCopy =
uint32_t (*)(v8::Local<v8::Value> receiver,
const v8::FastApiTypedArray<uint8_t>& source,
const v8::FastApiTypedArray<uint8_t>& target,
v8::Local<v8::Value> source,
v8::Local<v8::Value> target,
uint32_t target_start,
uint32_t source_start,
uint32_t to_copy);
uint32_t to_copy,
v8::FastApiCallbackOptions&);

// This class manages the external references from the V8 heap
// to the C++ addresses in Node.js.
Expand All @@ -98,9 +85,6 @@ class ExternalReferenceRegistry {
V(CFunctionCallbackWithBool) \
V(CFunctionCallbackWithString) \
V(CFunctionCallbackWithStrings) \
V(CFunctionCallbackWithTwoUint8Arrays) \
V(CFunctionCallbackWithTwoUint8ArraysFallback) \
V(CFunctionCallbackWithUint8ArrayUint32Int64Bool) \
V(CFunctionWithUint32) \
V(CFunctionWithDoubleReturnDouble) \
V(CFunctionWithInt64Fallback) \
Expand Down

0 comments on commit d1bffa9

Please sign in to comment.