Skip to content

Commit 0697f8b

Browse files
committed
smalloc: validate arguments in js
PR-URL: #920 Reviewed-By: Chris Dickinson <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent 08133f4 commit 0697f8b

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

lib/smalloc.js

+36-6
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ const kMaxLength = smalloc.kMaxLength;
55
const util = require('util');
66

77
exports.alloc = alloc;
8-
exports.copyOnto = smalloc.copyOnto;
8+
exports.copyOnto = copyOnto;
99
exports.dispose = dispose;
10-
exports.hasExternalData = smalloc.hasExternalData;
10+
exports.hasExternalData = hasExternalData;
1111

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

53+
if (Array.isArray(obj))
54+
throw new TypeError('obj cannot be an array');
55+
if (obj instanceof Buffer)
56+
throw new TypeError('obj cannot be a Buffer');
57+
if (smalloc.isTypedArray(obj))
58+
throw new TypeError('obj cannot be a typed array');
59+
if (smalloc.hasExternalData(obj))
60+
throw new TypeError('object already has external array data');
61+
5362
// 1 == v8::kExternalUint8Array, 9 == v8::kExternalUint8ClampedArray
5463
if (type < 1 || type > 9)
5564
throw new TypeError('unknown external array type: ' + type);
56-
if (Array.isArray(obj))
57-
throw new TypeError('Arrays are not supported');
5865
if (n > kMaxLength)
59-
throw new RangeError('n > kMaxLength');
66+
throw new RangeError('Attempt to allocate array larger than maximum ' +
67+
'size: 0x' + kMaxLength.toString(16) + ' elements');
6068

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

7583
smalloc.dispose(obj);
7684
}
85+
86+
87+
function copyOnto(source, sourceStart, dest, destStart, copyLength) {
88+
if (util.isPrimitive(source))
89+
throw new TypeError('source must be an Object');
90+
if (util.isPrimitive(dest))
91+
throw new TypeError('dest must be an Object');
92+
if (!smalloc.hasExternalData(source))
93+
throw new TypeError('source has no external array data');
94+
if (!smalloc.hasExternalData(dest))
95+
throw new TypeError('dest has no external array data');
96+
97+
return smalloc.copyOnto(source, sourceStart, dest, destStart, copyLength);
98+
}
99+
100+
101+
function hasExternalData(obj) {
102+
if (util.isPrimitive(obj))
103+
return false;
104+
105+
return smalloc.hasExternalData(obj);
106+
}

src/smalloc.cc

+9-13
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,14 @@ size_t ExternalArraySize(enum ExternalArrayType type) {
152152
void CopyOnto(const FunctionCallbackInfo<Value>& args) {
153153
Environment* env = Environment::GetCurrent(args);
154154

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

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

163-
if (!source->HasIndexedPropertiesInExternalArrayData())
164-
return env->ThrowError("source has no external array data");
165-
if (!dest->HasIndexedPropertiesInExternalArrayData())
166-
return env->ThrowError("dest has no external array data");
161+
ASSERT(source->HasIndexedPropertiesInExternalArrayData());
162+
ASSERT(dest->HasIndexedPropertiesInExternalArrayData());
167163

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

265+
ASSERT(args[0]->IsObject());
266+
269267
Local<Object> obj = args[0].As<Object>();
270268

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

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

411407
void HasExternalData(const FunctionCallbackInfo<Value>& args) {
412408
Environment* env = Environment::GetCurrent(args);
413-
args.GetReturnValue().Set(args[0]->IsObject() &&
414-
HasExternalData(env, args[0].As<Object>()));
409+
ASSERT(args[0]->IsObject());
410+
args.GetReturnValue().Set(HasExternalData(env, args[0].As<Object>()));
415411
}
416412

417413

0 commit comments

Comments
 (0)