Browse Source

buffer: remove float write range checks

Removed range checks when writing float values, and removed a few
includes and defines. Also updated api docs to reflect that invalid 32
bit float is an unspecified behavior.
v0.9.8-release
Trevor Norris 12 years ago
committed by Ben Noordhuis
parent
commit
3d286b68be
  1. 2
      doc/api/buffer.markdown
  2. 50
      src/node_buffer.cc

2
doc/api/buffer.markdown

@ -626,7 +626,7 @@ complement signed integer into `buffer`.
* `noAssert` Boolean, Optional, Default: false
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 32 bit float.
format. Note, behavior is unspecified if `value` is not a 32 bit float.
Set `noAssert` to true to skip validation of `value` and `offset`. This means
that `value` may be too large for the specific function and `offset` may be

50
src/node_buffer.cc

@ -28,32 +28,6 @@
#include <assert.h>
#include <string.h> // memcpy
#include <float.h> // float limits
#include <math.h> // infinity
// Windows does not define INFINITY in math.h
// Copy V8's approach and use HUGE_VAL instead
#ifndef INFINITY
# ifdef HUGE_VALF
# define INFINITY HUGE_VALF
# else
// MSVC. No INFINITY, no HUGE_VALF
// There's HUGE_VAL, but that's a double, not a float.
// Assign the bytes and float-ify it.
typedef union { unsigned char __c[4]; float __f; } __huge_valf_t;
# if __BYTE_ORDER == __BIG_ENDIAN
# define __HUGE_VALF_bytes { 0x7f, 0x80, 0, 0 }
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define __HUGE_VALF_bytes { 0, 0, 0x80, 0x7f }
# endif
static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
# define INFINITY (__huge_valf.__f)
# endif
#endif
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@ -713,16 +687,6 @@ static void swizzle(char* buf, size_t len) {
}
inline bool OutOfRangeCheck(float val, double val_tmp) {
if ((val_tmp > 0 && (val_tmp > FLT_MAX || val_tmp < FLT_MIN)
&& val_tmp != INFINITY) ||
((val_tmp < 0 && (val_tmp < -FLT_MAX || val_tmp > -FLT_MIN)
&& val_tmp != -INFINITY)))
return true;
return false;
}
template <typename T, bool ENDIANNESS>
Handle<Value> ReadFloatGeneric(const Arguments& args) {
double offset_tmp = args[0]->NumberValue();
@ -779,24 +743,20 @@ Handle<Value> WriteFloatGeneric(const Arguments& args) {
if (doAssert) {
if (!args[0]->IsNumber())
return ThrowTypeError("value not a number");
if (!args[1]->IsUint32())
return ThrowTypeError("offset is not uint");
}
double val_tmp = args[0]->NumberValue();
T val = static_cast<T>(val_tmp);
double offset_tmp = args[1]->NumberValue();
int64_t offset = static_cast<int64_t>(offset_tmp);
T val = static_cast<T>(args[0]->NumberValue());
size_t offset = args[1]->Uint32Value();
char* data = static_cast<char*>(
args.This()->GetIndexedPropertiesExternalArrayData());
char* ptr = data + offset;
if (doAssert) {
if (offset_tmp != offset || offset < 0)
return ThrowTypeError("offset is not uint");
if (sizeof(T) == 4 && OutOfRangeCheck(val, val_tmp))
return ThrowRangeError("value is out of type range");
size_t len = static_cast<size_t>(
args.This()->GetIndexedPropertiesExternalArrayDataLength());
if (offset + sizeof(T) > len)
if (offset + sizeof(T) > len || offset + sizeof(T) < offset)
return ThrowRangeError("Trying to write beyond buffer length");
}

Loading…
Cancel
Save