Skip to content

Commit

Permalink
smalloc: validate arguments in js
Browse files Browse the repository at this point in the history
PR-URL: #920
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
  • Loading branch information
vkurchatkin committed Mar 4, 2015
1 parent 08133f4 commit 0697f8b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
42 changes: 36 additions & 6 deletions lib/smalloc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ const kMaxLength = smalloc.kMaxLength;
const util = require('util');

exports.alloc = alloc;
exports.copyOnto = smalloc.copyOnto;
exports.copyOnto = copyOnto;
exports.dispose = dispose;
exports.hasExternalData = smalloc.hasExternalData;
exports.hasExternalData = hasExternalData;

// don't allow kMaxLength to accidentally be overwritten. it's a lot less
// apparent when a primitive is accidentally changed.
Expand Down Expand Up @@ -50,13 +50,21 @@ function alloc(n, obj, type) {
throw new TypeError('obj must be an Object');
}

if (Array.isArray(obj))
throw new TypeError('obj cannot be an array');
if (obj instanceof Buffer)
throw new TypeError('obj cannot be a Buffer');
if (smalloc.isTypedArray(obj))
throw new TypeError('obj cannot be a typed array');
if (smalloc.hasExternalData(obj))
throw new TypeError('object already has external array data');

// 1 == v8::kExternalUint8Array, 9 == v8::kExternalUint8ClampedArray
if (type < 1 || type > 9)
throw new TypeError('unknown external array type: ' + type);
if (Array.isArray(obj))
throw new TypeError('Arrays are not supported');
if (n > kMaxLength)
throw new RangeError('n > kMaxLength');
throw new RangeError('Attempt to allocate array larger than maximum ' +
'size: 0x' + kMaxLength.toString(16) + ' elements');

return smalloc.alloc(obj, n, type);
}
Expand All @@ -70,7 +78,29 @@ function dispose(obj) {
if (smalloc.isTypedArray(obj))
throw new TypeError('obj cannot be a typed array');
if (!smalloc.hasExternalData(obj))
throw new Error('obj has no external array data');
throw new TypeError('obj has no external array data');

smalloc.dispose(obj);
}


function copyOnto(source, sourceStart, dest, destStart, copyLength) {
if (util.isPrimitive(source))
throw new TypeError('source must be an Object');
if (util.isPrimitive(dest))
throw new TypeError('dest must be an Object');
if (!smalloc.hasExternalData(source))
throw new TypeError('source has no external array data');
if (!smalloc.hasExternalData(dest))
throw new TypeError('dest has no external array data');

return smalloc.copyOnto(source, sourceStart, dest, destStart, copyLength);
}


function hasExternalData(obj) {
if (util.isPrimitive(obj))
return false;

return smalloc.hasExternalData(obj);
}
22 changes: 9 additions & 13 deletions src/smalloc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,14 @@ size_t ExternalArraySize(enum ExternalArrayType type) {
void CopyOnto(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

if (!args[0]->IsObject())
return env->ThrowTypeError("source must be an object");
if (!args[2]->IsObject())
return env->ThrowTypeError("dest must be an object");
ASSERT(args[0]->IsObject());
ASSERT(args[2]->IsObject());

Local<Object> source = args[0].As<Object>();
Local<Object> dest = args[2].As<Object>();

if (!source->HasIndexedPropertiesInExternalArrayData())
return env->ThrowError("source has no external array data");
if (!dest->HasIndexedPropertiesInExternalArrayData())
return env->ThrowError("dest has no external array data");
ASSERT(source->HasIndexedPropertiesInExternalArrayData());
ASSERT(dest->HasIndexedPropertiesInExternalArrayData());

size_t source_start = args[1]->Uint32Value();
size_t dest_start = args[3]->Uint32Value();
Expand Down Expand Up @@ -266,11 +262,11 @@ void SliceOnto(const FunctionCallbackInfo<Value>& args) {
void Alloc(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

ASSERT(args[0]->IsObject());

Local<Object> obj = args[0].As<Object>();

// can't perform this check in JS
if (obj->HasIndexedPropertiesInExternalArrayData())
return env->ThrowTypeError("object already has external array data");
ASSERT(!obj->HasIndexedPropertiesInExternalArrayData());

size_t length = args[1]->Uint32Value();
enum ExternalArrayType array_type;
Expand Down Expand Up @@ -410,8 +406,8 @@ void Alloc(Environment* env,

void HasExternalData(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
args.GetReturnValue().Set(args[0]->IsObject() &&
HasExternalData(env, args[0].As<Object>()));
ASSERT(args[0]->IsObject());
args.GetReturnValue().Set(HasExternalData(env, args[0].As<Object>()));
}


Expand Down

0 comments on commit 0697f8b

Please sign in to comment.