From a28d54e95156f05f708739b7e3697989b70983cb Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 3 Mar 2010 16:20:41 -0800 Subject: [PATCH] b=543682; don't let js array holes escape via typed arrays; r=jorendorff --- js/src/jstypedarray.cpp | 11 ++++++++++- js/src/tests/js1_8_5/extensions/typedarray.js | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/js/src/jstypedarray.cpp b/js/src/jstypedarray.cpp index 7d250537070a..16f832a7640d 100644 --- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -920,7 +920,7 @@ class TypedArrayTemplate { NativeType *dest = static_cast(data); - if (ar->isDenseArray()) { + if (ar->isDenseArray() && js_DenseArrayCapacity(ar) >= len) { JS_ASSERT(ar->fslots[JSSLOT_ARRAY_LENGTH] == (jsval)len); jsval *src = ar->dslots; @@ -931,6 +931,12 @@ class TypedArrayTemplate *dest++ = NativeType(JSVAL_TO_INT(v)); } else if (JSVAL_IS_DOUBLE(v)) { *dest++ = NativeType(*JSVAL_TO_DOUBLE(v)); + } else if (v == JSVAL_HOLE) { + // Holes convert to 0. + // XXX for floating-point arrays, they should convert to NaN + // Note that the int32() is necessary, because on MSVC int32 is not the + // same as int, and there's no constructor for uint8_clamped(int). + *dest++ = NativeType(int32(0)); } else { jsdouble dval; if (!JS_ValueToNumber(cx, v, &dval)) @@ -950,6 +956,9 @@ class TypedArrayTemplate *dest++ = NativeType(JSVAL_TO_INT(v)); } else if (JSVAL_IS_DOUBLE(v)) { *dest++ = NativeType(*JSVAL_TO_DOUBLE(v)); + } else if (v == JSVAL_VOID) { + // See earlier comment about why int32(0) is necessary + *dest++ = NativeType(int32(0)); } else { jsdouble dval; if (!JS_ValueToNumber(cx, v, &dval)) diff --git a/js/src/tests/js1_8_5/extensions/typedarray.js b/js/src/tests/js1_8_5/extensions/typedarray.js index c4cca12216d5..24262b90abe9 100644 --- a/js/src/tests/js1_8_5/extensions/typedarray.js +++ b/js/src/tests/js1_8_5/extensions/typedarray.js @@ -194,6 +194,21 @@ function test() check(function() a[2] == 0); check(function() a[3] == 0); + // check handling of holes and non-numeric values + var x = Array(3); + x[0] = "hello"; + x[1] = { }; + + a = new Uint8Array(x); + check(function() a[0] == 0); + check(function() a[1] == 0); + check(function() a[2] == 0); + + a = new Float32Array(x); + check(function() a[0] == NaN, TODO); // XXX should be NaN, not 0, most likely + check(function() a[1] == NaN); + check(function() a[2] == NaN); + print ("done"); reportCompare(0, TestFailCount, "typed array tests");