Skip to content

Commit

Permalink
Array fixes (#467)
Browse files Browse the repository at this point in the history
Fixes for Array implementation:

* fix ctor parameter check
* fix argument range checks
* some length fixes
  • Loading branch information
rbri authored and gbrail committed Aug 8, 2018
1 parent 2f5b476 commit a5d9553
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 63 deletions.
12 changes: 9 additions & 3 deletions src/org/mozilla/javascript/NativeArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import org.mozilla.javascript.regexp.NativeRegExp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
Expand Down Expand Up @@ -515,16 +516,16 @@ public Object[] getIds(boolean nonEnumerable, boolean getSymbols)
return ids;
}

public Integer[] getIndexIds() {
public List<Integer> getIndexIds() {
Object[] ids = getIds();
java.util.List<Integer> indices = new java.util.ArrayList<Integer>(ids.length);
List<Integer> indices = new ArrayList<Integer>(ids.length);
for (Object id : ids) {
int int32Id = ScriptRuntime.toInt32(id);
if (int32Id >= 0 && ScriptRuntime.toString(int32Id).equals(ScriptRuntime.toString(id))) {
indices.add(int32Id);
}
}
return indices.toArray(new Integer[indices.size()]);
return indices;
}

@Override
Expand Down Expand Up @@ -727,6 +728,11 @@ static long getLengthProperty(Context cx, Scriptable obj) {
// toUint32(undefined) == 0
return 0;
}

double doubleLen = ScriptRuntime.toNumber(len);
if (doubleLen < 0) {
return 0;
}
return ScriptRuntime.toUint32(len);
}

Expand Down
30 changes: 19 additions & 11 deletions src/org/mozilla/javascript/typedarrays/NativeArrayBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,23 @@ public NativeArrayBuffer()
/**
* Create a buffer of the specified length in bytes.
*/
public NativeArrayBuffer(int len)
public NativeArrayBuffer(double len)
{
if (len < 0) {
if (len >= Integer.MAX_VALUE) {
throw ScriptRuntime.constructError("RangeError", "length parameter (" + len + ") is too large ");
}
if (len == Double.NEGATIVE_INFINITY) {
throw ScriptRuntime.constructError("RangeError", "Negative array length " + len);
}

int intLen = ScriptRuntime.toInt32(len);
if (intLen < 0) {
throw ScriptRuntime.constructError("RangeError", "Negative array length " + len);
}
if (len == 0) {
if (intLen == 0) {
buffer = EMPTY_BUF;
} else {
buffer = new byte[len];
buffer = new byte[intLen];
}
}

Expand Down Expand Up @@ -93,12 +101,12 @@ public byte[] getBuffer() {
* @param s the position where the new buffer will start
* @param e the position where it will end
*/
public NativeArrayBuffer slice(int s, int e)
public NativeArrayBuffer slice(double s, double e)
{
// Handle negative start and and as relative to start
// Handle negative start as relative to start
// Clamp as per the spec to between 0 and length
int end = Math.max(0, Math.min(buffer.length, (e < 0 ? buffer.length + e : e)));
int start = Math.min(end, Math.max(0, (s < 0 ? buffer.length + s : s)));
int end = ScriptRuntime.toInt32(Math.max(0, Math.min(buffer.length, (e < 0 ? buffer.length + e : e))));
int start = ScriptRuntime.toInt32(Math.min(end, Math.max(0, (s < 0 ? buffer.length + s : s))));
int len = end - start;

NativeArrayBuffer newBuf = new NativeArrayBuffer(len);
Expand All @@ -121,13 +129,13 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
return (isArg(args, 0) && (args[0] instanceof NativeArrayBufferView));

case Id_constructor:
int length = isArg(args, 0) ? ScriptRuntime.toInt32(args[0]) : 0;
double length = isArg(args, 0) ? ScriptRuntime.toNumber(args[0]) : 0;
return new NativeArrayBuffer(length);

case Id_slice:
NativeArrayBuffer self = realThis(thisObj, f);
int start = isArg(args, 0) ? ScriptRuntime.toInt32(args[0]) : 0;
int end = isArg(args, 1) ? ScriptRuntime.toInt32(args[1]) : self.buffer.length;
double start = isArg(args, 0) ? ScriptRuntime.toNumber(args[0]) : 0;
double end = isArg(args, 1) ? ScriptRuntime.toNumber(args[1]) : self.buffer.length;
return self.slice(start, end);
}
throw new IllegalArgumentException(String.valueOf(id));
Expand Down
18 changes: 11 additions & 7 deletions testsrc/org/mozilla/javascript/tests/NativeArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import org.junit.Before;

import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.Arrays;

import static org.hamcrest.core.Is.is;

import org.mozilla.javascript.NativeArray;
Expand Down Expand Up @@ -74,44 +78,44 @@ public void hasShouldBeFalseForANewArray() {

@Test
public void getIndexIdsShouldBeEmptyForEmptyArray() {
assertThat(new NativeArray(0).getIndexIds(), is(new Integer[]{}));
assertThat(new NativeArray(0).getIndexIds(), is(new ArrayList<Integer>()));
}

@Test
public void getIndexIdsShouldBeAZeroForSimpleSingletonArray() {
array.put(0, array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{ 0 }));
assertThat(array.getIndexIds(), is(Arrays.asList(0)));
}

@Test
public void getIndexIdsShouldWorkWhenIndicesSetAsString() {
array.put("0", array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{ 0 }));
assertThat(array.getIndexIds(), is(Arrays.asList(0)));
}

@Test
public void getIndexIdsShouldNotIncludeNegativeIds() {
array.put(-1, array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{}));
assertThat(array.getIndexIds(), is(new ArrayList<Integer>()));
}

@Test
public void getIndexIdsShouldIncludeIdsLessThan2ToThe32() {
int maxIndex = (int) (1L << 31) - 1;
array.put(maxIndex, array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{ maxIndex }));
assertThat(array.getIndexIds(), is(Arrays.asList(maxIndex)));
}

@Test
public void getIndexIdsShouldNotIncludeIdsGreaterThanOrEqualTo2ToThe32() {
array.put((1L<<31)+"", array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{}));
assertThat(array.getIndexIds(), is(new ArrayList<Integer>()));
}

@Test
public void getIndexIdsShouldNotReturnNonNumericIds() {
array.put("x", array, "a");
assertThat(array.getIndexIds(), is(new Integer[]{}));
assertThat(array.getIndexIds(), is(new ArrayList<Integer>()));
}

}
42 changes: 0 additions & 42 deletions testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,32 @@

built-ins/Array
# incorrect length handling
! every/15.4.4.16-3-7
! every/15.4.4.16-3-8
! every/15.4.4.16-3-12
! every/15.4.4.16-3-14
! every/15.4.4.16-3-25
! every/15.4.4.16-3-29
! filter/15.4.4.20-3-7
! filter/15.4.4.20-3-12
! filter/15.4.4.20-3-25
! forEach/15.4.4.18-3-7
! forEach/15.4.4.18-3-12
! forEach/15.4.4.18-3-25
! indexOf/15.4.4.14-3-7
! indexOf/15.4.4.14-3-8
! indexOf/15.4.4.14-3-12
! indexOf/15.4.4.14-3-14
! indexOf/15.4.4.14-3-25
! indexOf/15.4.4.14-3-28
! indexOf/15.4.4.14-3-29
! join/S15.4.4.5_A4_T3
! lastIndexOf/15.4.4.15-3-7
! lastIndexOf/15.4.4.15-3-12
! lastIndexOf/15.4.4.15-3-25
! lastIndexOf/15.4.4.15-3-28
! map/15.4.4.19-3-7
! map/15.4.4.19-3-8
! map/15.4.4.19-3-12
! map/15.4.4.19-3-14
! map/15.4.4.19-3-25
! map/15.4.4.19-3-28
! map/15.4.4.19-3-29
! pop/S15.4.4.6_A2_T2
! pop/S15.4.4.6_A3_T1
! pop/S15.4.4.6_A3_T2
! pop/S15.4.4.6_A3_T3
! push/S15.4.4.7_A2_T2
! push/S15.4.4.7_A4_T1
! push/S15.4.4.7_A4_T3
! reduce/15.4.4.21-3-7
! reduce/15.4.4.21-3-12
! reduce/15.4.4.21-3-25
! reduceRight/15.4.4.22-3-7
! reduceRight/15.4.4.22-3-12
! reduceRight/15.4.4.22-3-25
! reverse/S15.4.4.8_A3_T3
! shift/S15.4.4.9_A3_T3
! slice/S15.4.4.10_A3_T1
! slice/S15.4.4.10_A3_T2
! slice/S15.4.4.10_A3_T3
! some/15.4.4.17-3-7
! some/15.4.4.17-3-8
! some/15.4.4.17-3-12
! some/15.4.4.17-3-14
! some/15.4.4.17-3-25
! some/15.4.4.17-3-28
! some/15.4.4.17-3-29
! sort/S15.4.4.11_A4_T3
! splice/S15.4.4.12_A3_T1
! splice/S15.4.4.12_A3_T3
! splice/S15.4.4.12_A6.1_T2
! unshift/S15.4.4.13_A3_T2
# bugs?
! splice/S15.4.4.12_A6.1_T3
# 'this === null' or 'this === undefined'
Expand Down Expand Up @@ -311,18 +276,12 @@ built-ins/Array
! throws-if-integer-limit-exceeded.js

built-ins/ArrayBuffer
! allocation-limit.js
! length-is-too-large-throws.js
! negative-length-throws.js
! prototype/byteLength/detached-buffer.js
! prototype/byteLength/invoked-as-accessor.js
! prototype/byteLength/length.js
! prototype/byteLength/name.js
! prototype/byteLength/prop-desc.js
! prototype/byteLength/this-is-sharedarraybuffer.js
! prototype/constructor.js
! prototype/slice/descriptor.js
! prototype/slice/end-exceeds-length.js
! prototype/slice/length.js
! prototype/slice/species-constructor-is-not-object.js
! prototype/slice/species-constructor-is-undefined.js
Expand All @@ -335,7 +294,6 @@ built-ins/ArrayBuffer
! prototype/slice/species-returns-same-arraybuffer.js
! prototype/slice/species-returns-smaller-arraybuffer.js
! prototype/slice/species.js
! prototype/slice/start-exceeds-length.js
! prototype/slice/this-is-sharedarraybuffer.js
! prototype/Symbol.toStringTag.js
! Symbol.species/length.js
Expand Down

0 comments on commit a5d9553

Please sign in to comment.