buffer: remove float write range checks
authorTrevor Norris <trev.norris@gmail.com>
Tue, 22 Jan 2013 22:35:20 +0000 (14:35 -0800)
committerBen Noordhuis <info@bnoordhuis.nl>
Wed, 23 Jan 2013 12:55:04 +0000 (13:55 +0100)
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.

doc/api/buffer.markdown
src/node_buffer.cc

index c2f3da8..3436626 100644 (file)
@@ -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
index 58f83d8..70c9c80 100644 (file)
 
 #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");
   }