mirror of https://github.com/nodejs/node.git
typed arrays: prevent unaligned typed array views on top of buffers
parent
285d8c6589
commit
973bbecf1a
|
@ -122,7 +122,7 @@ class ArrayBuffer {
|
|||
}
|
||||
};
|
||||
|
||||
static bool checkAlignment(unsigned int val, unsigned int bytes) {
|
||||
static bool checkAlignment(size_t val, unsigned int bytes) {
|
||||
return (val & (bytes - 1)) == 0; // Handles bytes == 0.
|
||||
}
|
||||
|
||||
|
@ -186,16 +186,13 @@ class TypedArray {
|
|||
if (node::Buffer::HasInstance(args[0])
|
||||
|| ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor.
|
||||
buffer = v8::Local<v8::Object>::Cast(args[0]);
|
||||
unsigned int buflen =
|
||||
size_t buflen =
|
||||
buffer->GetIndexedPropertiesExternalArrayDataLength();
|
||||
|
||||
if (!args[1]->IsUndefined() && args[1]->Int32Value() < 0)
|
||||
return ThrowRangeError("Byte offset out of range.");
|
||||
byte_offset = args[1]->IsUndefined() ? 0 : args[1]->Uint32Value();
|
||||
|
||||
if (!checkAlignment(byte_offset, TBytes))
|
||||
return ThrowRangeError("Byte offset is not aligned.");
|
||||
|
||||
if (args.Length() > 2) {
|
||||
if (args[2]->Int32Value() < 0)
|
||||
return ThrowRangeError("Length out of range.");
|
||||
|
@ -214,10 +211,14 @@ class TypedArray {
|
|||
return ThrowRangeError("Length is out of range.");
|
||||
}
|
||||
|
||||
// TODO(deanm): Error check.
|
||||
void* buf = buffer->GetIndexedPropertiesExternalArrayData();
|
||||
char* begin = reinterpret_cast<char*>(buf) + byte_offset;
|
||||
|
||||
if (!checkAlignment(reinterpret_cast<uintptr_t>(begin), TBytes))
|
||||
return ThrowRangeError("Byte offset is not aligned.");
|
||||
|
||||
args.This()->SetIndexedPropertiesToExternalArrayData(
|
||||
reinterpret_cast<char*>(buf) + byte_offset, TEAType, length);
|
||||
begin, TEAType, length);
|
||||
}
|
||||
else if (args[0]->IsObject()) { // TypedArray / type[] constructor.
|
||||
v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]);
|
||||
|
|
|
@ -53,13 +53,28 @@ var assert = require('assert');
|
|||
});
|
||||
|
||||
// initialize a zero-filled buffer
|
||||
var buffer = new Buffer(8);
|
||||
var buffer = new Buffer(16);
|
||||
buffer.fill(0);
|
||||
|
||||
var uint8 = new Uint8Array(buffer);
|
||||
var uint16 = new Uint16Array(buffer);
|
||||
var uint16slice = new Uint16Array(buffer, 2, 2);
|
||||
var uint32 = new Uint32Array(buffer);
|
||||
// only one of these instantiations should succeed, as the other ones will be
|
||||
// unaligned
|
||||
var errors = 0;
|
||||
var offset;
|
||||
for (var i = 0; i < 8; i++) {
|
||||
try {
|
||||
new Float64Array(buffer, i);
|
||||
offset = i;
|
||||
} catch (e) {
|
||||
errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert.equal(errors, 7);
|
||||
|
||||
var uint8 = new Uint8Array(buffer, offset);
|
||||
var uint16 = new Uint16Array(buffer, offset);
|
||||
var uint16slice = new Uint16Array(buffer, offset + 2, 2);
|
||||
var uint32 = new Uint32Array(buffer, offset);
|
||||
|
||||
assert.equal(uint8.BYTES_PER_ELEMENT, 1);
|
||||
assert.equal(uint16.BYTES_PER_ELEMENT, 2);
|
||||
|
@ -67,20 +82,19 @@ assert.equal(uint16slice.BYTES_PER_ELEMENT, 2);
|
|||
assert.equal(uint32.BYTES_PER_ELEMENT, 4);
|
||||
|
||||
// now change the underlying buffer
|
||||
buffer[0] = 0x08;
|
||||
buffer[1] = 0x09;
|
||||
buffer[2] = 0x0a;
|
||||
buffer[3] = 0x0b;
|
||||
buffer[4] = 0x0c;
|
||||
buffer[5] = 0x0d;
|
||||
buffer[6] = 0x0e;
|
||||
buffer[7] = 0x0f;
|
||||
buffer[offset ] = 0x08;
|
||||
buffer[offset + 1] = 0x09;
|
||||
buffer[offset + 2] = 0x0a;
|
||||
buffer[offset + 3] = 0x0b;
|
||||
buffer[offset + 4] = 0x0c;
|
||||
buffer[offset + 5] = 0x0d;
|
||||
buffer[offset + 6] = 0x0e;
|
||||
buffer[offset + 7] = 0x0f;
|
||||
|
||||
/*
|
||||
This is what we expect the variables to look like at this point (on
|
||||
little-endian machines):
|
||||
|
||||
buffer | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
|
||||
uint8 | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
|
||||
uint16 | 0x0908 | 0x0b0a | 0x0d0c | 0x0f0e |
|
||||
uint16slice --------------| 0x0b0a | 0x0d0c |--------------
|
||||
|
|
Loading…
Reference in New Issue