Skip to content

Commit

Permalink
typed arrays: fix 32 bit size/index overflow
Browse files Browse the repository at this point in the history
Fix an out-of-bound read/write bug due to integer wrapping. Reported by
Dean McNamee.
  • Loading branch information
bnoordhuis committed Jan 9, 2013
1 parent aa742dd commit ed825f4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/v8_typed_array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <stdlib.h> // calloc, etc
#include <string.h> // memmove
#include <stdint.h>

#include "v8_typed_array.h"
#include "node_buffer.h"
Expand Down Expand Up @@ -722,11 +723,14 @@ class DataView {
// TODO(deanm): All of these things should be cacheable.
int element_size = SizeOfArrayElementForType(
args.This()->GetIndexedPropertiesExternalArrayDataType());
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() *
element_size;
assert(element_size > 0);
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
assert(size >= 0);

if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow.
if (static_cast<uint64_t>(index) + sizeof(T) >
static_cast<uint64_t>(size) * element_size) {
return ThrowError("Index out of range.");
}

void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
return cTypeToValue<T>(getValue<T>(ptr, index, !little_endian));
Expand All @@ -742,11 +746,14 @@ class DataView {
// TODO(deanm): All of these things should be cacheable.
int element_size = SizeOfArrayElementForType(
args.This()->GetIndexedPropertiesExternalArrayDataType());
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() *
element_size;
assert(element_size > 0);
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
assert(size >= 0);

if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow.
if (static_cast<uint64_t>(index) + sizeof(T) >
static_cast<uint64_t>(size) * element_size) {
return ThrowError("Index out of range.");
}

void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
setValue<T>(ptr, index, valueToCType<T>(args[1]), !little_endian);
Expand Down
10 changes: 10 additions & 0 deletions test/simple/test-typed-arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,13 @@ assert.equal(uint8c[1], 255);
var view = new DataView(array.buffer);
for (var i = 128; i <= 255; ++i) assert.equal(view.getInt8(i - 128), i - 256);
})();

assert.throws(function() {
var buf = new DataView(new ArrayBuffer(8));
buf.getFloat64(0xffffffff, true);
}, /Index out of range/);

assert.throws(function() {
var buf = new DataView(new ArrayBuffer(8));
buf.setFloat64(0xffffffff, 0.0, true);
}, /Index out of range/);

0 comments on commit ed825f4

Please sign in to comment.