Browse Source

smalloc: validate arguments in js

PR-URL: https://github.com/iojs/io.js/pull/920
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
v1.8.0-commit
Vladimir Kurchatkin 10 years ago
parent
commit
0697f8b44d
  1. 42
      lib/smalloc.js
  2. 22
      src/smalloc.cc

42
lib/smalloc.js

@ -5,9 +5,9 @@ const kMaxLength = smalloc.kMaxLength;
const util = require('util'); const util = require('util');
exports.alloc = alloc; exports.alloc = alloc;
exports.copyOnto = smalloc.copyOnto; exports.copyOnto = copyOnto;
exports.dispose = dispose; exports.dispose = dispose;
exports.hasExternalData = smalloc.hasExternalData; exports.hasExternalData = hasExternalData;
// don't allow kMaxLength to accidentally be overwritten. it's a lot less // don't allow kMaxLength to accidentally be overwritten. it's a lot less
// apparent when a primitive is accidentally changed. // apparent when a primitive is accidentally changed.
@ -50,13 +50,21 @@ function alloc(n, obj, type) {
throw new TypeError('obj must be an Object'); 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 // 1 == v8::kExternalUint8Array, 9 == v8::kExternalUint8ClampedArray
if (type < 1 || type > 9) if (type < 1 || type > 9)
throw new TypeError('unknown external array type: ' + type); throw new TypeError('unknown external array type: ' + type);
if (Array.isArray(obj))
throw new TypeError('Arrays are not supported');
if (n > kMaxLength) 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); return smalloc.alloc(obj, n, type);
} }
@ -70,7 +78,29 @@ function dispose(obj) {
if (smalloc.isTypedArray(obj)) if (smalloc.isTypedArray(obj))
throw new TypeError('obj cannot be a typed array'); throw new TypeError('obj cannot be a typed array');
if (!smalloc.hasExternalData(obj)) 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); 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
src/smalloc.cc

@ -152,18 +152,14 @@ size_t ExternalArraySize(enum ExternalArrayType type) {
void CopyOnto(const FunctionCallbackInfo<Value>& args) { void CopyOnto(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
if (!args[0]->IsObject()) ASSERT(args[0]->IsObject());
return env->ThrowTypeError("source must be an object"); ASSERT(args[2]->IsObject());
if (!args[2]->IsObject())
return env->ThrowTypeError("dest must be an object");
Local<Object> source = args[0].As<Object>(); Local<Object> source = args[0].As<Object>();
Local<Object> dest = args[2].As<Object>(); Local<Object> dest = args[2].As<Object>();
if (!source->HasIndexedPropertiesInExternalArrayData()) ASSERT(source->HasIndexedPropertiesInExternalArrayData());
return env->ThrowError("source has no external array data"); ASSERT(dest->HasIndexedPropertiesInExternalArrayData());
if (!dest->HasIndexedPropertiesInExternalArrayData())
return env->ThrowError("dest has no external array data");
size_t source_start = args[1]->Uint32Value(); size_t source_start = args[1]->Uint32Value();
size_t dest_start = args[3]->Uint32Value(); size_t dest_start = args[3]->Uint32Value();
@ -266,11 +262,11 @@ void SliceOnto(const FunctionCallbackInfo<Value>& args) {
void Alloc(const FunctionCallbackInfo<Value>& args) { void Alloc(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
ASSERT(args[0]->IsObject());
Local<Object> obj = args[0].As<Object>(); Local<Object> obj = args[0].As<Object>();
// can't perform this check in JS ASSERT(!obj->HasIndexedPropertiesInExternalArrayData());
if (obj->HasIndexedPropertiesInExternalArrayData())
return env->ThrowTypeError("object already has external array data");
size_t length = args[1]->Uint32Value(); size_t length = args[1]->Uint32Value();
enum ExternalArrayType array_type; enum ExternalArrayType array_type;
@ -410,8 +406,8 @@ void Alloc(Environment* env,
void HasExternalData(const FunctionCallbackInfo<Value>& args) { void HasExternalData(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
args.GetReturnValue().Set(args[0]->IsObject() && ASSERT(args[0]->IsObject());
HasExternalData(env, args[0].As<Object>())); args.GetReturnValue().Set(HasExternalData(env, args[0].As<Object>()));
} }

Loading…
Cancel
Save