Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buffer: move checkFloat from lib into src #3763

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1028,20 +1028,13 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
};


function checkFloat(buffer, value, offset, ext) {
if (!(buffer instanceof Buffer))
throw new TypeError('"buffer" argument must be a Buffer instance');
if (offset + ext > buffer.length)
throw new RangeError('Index out of range');
}


Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
checkFloat(this, val, offset, 4);
binding.writeFloatLE(this, val, offset);
binding.writeFloatLE(this, val, offset);
else
binding.writeFloatLE(this, val, offset, true);
return offset + 4;
};

Expand All @@ -1050,8 +1043,9 @@ Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
checkFloat(this, val, offset, 4);
binding.writeFloatBE(this, val, offset);
binding.writeFloatBE(this, val, offset);
else
binding.writeFloatBE(this, val, offset, true);
return offset + 4;
};

Expand All @@ -1060,8 +1054,9 @@ Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
checkFloat(this, val, offset, 8);
binding.writeDoubleLE(this, val, offset);
binding.writeDoubleLE(this, val, offset);
else
binding.writeDoubleLE(this, val, offset, true);
return offset + 8;
};

Expand All @@ -1070,7 +1065,8 @@ Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
checkFloat(this, val, offset, 8);
binding.writeDoubleBE(this, val, offset);
binding.writeDoubleBE(this, val, offset);
else
binding.writeDoubleBE(this, val, offset, true);
return offset + 8;
};
43 changes: 30 additions & 13 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -730,15 +730,37 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {


template <typename T, enum Endianness endianness>
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
SPREAD_ARG(args[0], ts_obj);
void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

bool should_assert = args.Length() < 4;

if (should_assert) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
}

Local<Uint8Array> ts_obj = args[0].As<Uint8Array>();
ArrayBuffer::Contents ts_obj_c = ts_obj->Buffer()->GetContents();
const size_t ts_obj_offset = ts_obj->ByteOffset();
const size_t ts_obj_length = ts_obj->ByteLength();
char* const ts_obj_data =
static_cast<char*>(ts_obj_c.Data()) + ts_obj_offset;
if (ts_obj_length > 0)
CHECK_NE(ts_obj_data, nullptr);

T val = args[1]->NumberValue(env->context()).FromMaybe(0);
size_t offset = args[2]->IntegerValue(env->context()).FromMaybe(0);

T val = args[1]->NumberValue();
uint32_t offset = args[2]->Uint32Value();
size_t memcpy_num = sizeof(T);
if (offset + sizeof(T) > ts_obj_length)
memcpy_num = ts_obj_length - offset;

if (should_assert) {
CHECK_NOT_OOB(offset + memcpy_num >= memcpy_num);
CHECK_NOT_OOB(offset + memcpy_num <= ts_obj_length);
}
CHECK_LE(offset + memcpy_num, ts_obj_length);

union NoAlias {
T val;
char bytes[sizeof(T)];
Expand All @@ -749,31 +771,26 @@ uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
if (endianness != GetEndianness())
Swizzle(na.bytes, sizeof(na.bytes));
memcpy(ptr, na.bytes, memcpy_num);
return offset + memcpy_num;
}


void WriteFloatLE(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
args.GetReturnValue().Set(WriteFloatGeneric<float, kLittleEndian>(args));
WriteFloatGeneric<float, kLittleEndian>(args);
}


void WriteFloatBE(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
args.GetReturnValue().Set(WriteFloatGeneric<float, kBigEndian>(args));
WriteFloatGeneric<float, kBigEndian>(args);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's still have WriteFloatGeneric return a value. Less spooky action at a distance, rather than have our return value set from a remote location.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type was changed since the THROW_AND_RETURN_UNLESS_BUFFER macro expands to include a return that is not of type uint32_t. Is it better to duplicate the macro logic here without the return?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, duh. That's actually why I initially implemented it this way. Thanks for the reminder. Yeah, leave it as is.

}


void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
args.GetReturnValue().Set(WriteFloatGeneric<double, kLittleEndian>(args));
WriteFloatGeneric<double, kLittleEndian>(args);
}


void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
args.GetReturnValue().Set(WriteFloatGeneric<double, kBigEndian>(args));
WriteFloatGeneric<double, kBigEndian>(args);
}


Expand Down