Fix uninitialized memory access (#68)

An alternative fix is to zero the `values` and `count` fields in
JS_NewObjectFromShape() irrespective of the object's class_id but
handling it in JS_GetPropertyValue() feels cleaner.

Fixes: https://github.com/quickjs-ng/quickjs/issues/63
This commit is contained in:
Ben Noordhuis 2023-11-17 00:12:10 +01:00 committed by GitHub
parent 98d9147fb2
commit 90d8c6bae0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7588,37 +7588,45 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj,
if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT && if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT &&
JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) {
JSObject *p; JSObject *p;
uint32_t idx, len; uint32_t idx;
/* fast path for array access */ /* fast path for array access */
p = JS_VALUE_GET_OBJ(this_obj); p = JS_VALUE_GET_OBJ(this_obj);
idx = JS_VALUE_GET_INT(prop); idx = JS_VALUE_GET_INT(prop);
len = (uint32_t)p->u.array.count;
if (unlikely(idx >= len))
goto slow_path;
switch(p->class_id) { switch(p->class_id) {
case JS_CLASS_ARRAY: case JS_CLASS_ARRAY:
case JS_CLASS_ARGUMENTS: case JS_CLASS_ARGUMENTS:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_DupValue(ctx, p->u.array.u.values[idx]); return JS_DupValue(ctx, p->u.array.u.values[idx]);
case JS_CLASS_INT8_ARRAY: case JS_CLASS_INT8_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewInt32(ctx, p->u.array.u.int8_ptr[idx]); return JS_NewInt32(ctx, p->u.array.u.int8_ptr[idx]);
case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8C_ARRAY:
case JS_CLASS_UINT8_ARRAY: case JS_CLASS_UINT8_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewInt32(ctx, p->u.array.u.uint8_ptr[idx]); return JS_NewInt32(ctx, p->u.array.u.uint8_ptr[idx]);
case JS_CLASS_INT16_ARRAY: case JS_CLASS_INT16_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewInt32(ctx, p->u.array.u.int16_ptr[idx]); return JS_NewInt32(ctx, p->u.array.u.int16_ptr[idx]);
case JS_CLASS_UINT16_ARRAY: case JS_CLASS_UINT16_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewInt32(ctx, p->u.array.u.uint16_ptr[idx]); return JS_NewInt32(ctx, p->u.array.u.uint16_ptr[idx]);
case JS_CLASS_INT32_ARRAY: case JS_CLASS_INT32_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewInt32(ctx, p->u.array.u.int32_ptr[idx]); return JS_NewInt32(ctx, p->u.array.u.int32_ptr[idx]);
case JS_CLASS_UINT32_ARRAY: case JS_CLASS_UINT32_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewUint32(ctx, p->u.array.u.uint32_ptr[idx]); return JS_NewUint32(ctx, p->u.array.u.uint32_ptr[idx]);
case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_INT64_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]); return JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]);
case JS_CLASS_BIG_UINT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]); return JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]);
case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT32_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return __JS_NewFloat64(ctx, p->u.array.u.float_ptr[idx]); return __JS_NewFloat64(ctx, p->u.array.u.float_ptr[idx]);
case JS_CLASS_FLOAT64_ARRAY: case JS_CLASS_FLOAT64_ARRAY:
if (unlikely(idx >= p->u.array.count)) goto slow_path;
return __JS_NewFloat64(ctx, p->u.array.u.double_ptr[idx]); return __JS_NewFloat64(ctx, p->u.array.u.double_ptr[idx]);
default: default:
goto slow_path; goto slow_path;