src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java

Print this page

        

@@ -273,11 +273,11 @@
 
         // Step 3b
         final PropertyDescriptor newLenDesc = desc;
 
         // Step 3c and 3d - get new length and convert to long
-        final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
+        final long newLen = NativeArray.validLength(newLenDesc.getValue());
 
         // Step 3e
         newLenDesc.setValue(newLen);
 
         // Step 3f

@@ -346,12 +346,12 @@
         // never be undefined as "length" is always defined and can't be deleted for arrays
         // Step 1
         final PropertyDescriptor oldLenDesc = (PropertyDescriptor) super.getOwnPropertyDescriptor("length");
 
         // Step 2
-        // get old length and convert to long
-        final long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
+        // get old length and convert to long. Always a Long/Uint32 but we take the safe road.
+        final long oldLen = JSType.toUint32(oldLenDesc.getValue());
 
         // Step 3
         if ("length".equals(key)) {
             // check for length being made non-writable
             final boolean result = defineLength(oldLen, oldLenDesc, desc, reject);

@@ -469,11 +469,11 @@
      * @param length new length property
      */
     @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
     public static void length(final Object self, final Object length) {
         if (isArray(self)) {
-            ((ScriptObject)self).setLength(validLength(length, true));
+            ((ScriptObject)self).setLength(validLength(length));
         }
     }
 
     /**
      * Prototype length getter

@@ -493,22 +493,17 @@
     @Setter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
     public static void setProtoLength(final Object self, final Object length) {
         length(self, length);  // Same as instance setter but we can't make nasgen use the same method for prototype
     }
 
-    static long validLength(final Object length, final boolean reject) {
+    static long validLength(final Object length) {
+        // ES5 15.4.5.1, steps 3.c and 3.d require two ToNumber conversions here
         final double doubleLength = JSType.toNumber(length);
-        if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) {
-            final long len = (long) doubleLength;
-            if (len >= 0 && len <= JSType.MAX_UINT) {
-                return len;
-            }
-        }
-        if (reject) {
+        if (doubleLength != JSType.toUint32(length)) {
             throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
         }
-        return -1;
+        return (long) doubleLength;
     }
 
     /**
      * ECMA 15.4.4.2 Array.prototype.toString ( )
      *