8130853: Non-extensible global is not handled property

Mon, 13 Jul 2015 20:09:14 +0530

author
sundar
date
Mon, 13 Jul 2015 20:09:14 +0530
changeset 1508
0c56e684d2c9
parent 1507
61b5174f7bf1
child 1509
533c66e9ad04

8130853: Non-extensible global is not handled property
Reviewed-by: jlaskey, hannesw

src/jdk/nashorn/internal/objects/Global.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptObject.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8130853.js file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/objects/Global.java	Wed Jul 22 10:18:33 2015 +0200
     1.2 +++ b/src/jdk/nashorn/internal/objects/Global.java	Mon Jul 13 20:09:14 2015 +0530
     1.3 @@ -2118,17 +2118,18 @@
     1.4              }
     1.5          }
     1.6  
     1.7 +        final boolean extensible = isExtensible();
     1.8          for (final jdk.nashorn.internal.runtime.Property property : properties) {
     1.9              if (property.isLexicalBinding()) {
    1.10                  assert lexScope != null;
    1.11 -                lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property);
    1.12 +                lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property, true);
    1.13  
    1.14                  if (ownMap.findProperty(property.getKey()) != null) {
    1.15                      // If property exists in the global object invalidate any global constant call sites.
    1.16                      invalidateGlobalConstant(property.getKey());
    1.17                  }
    1.18              } else {
    1.19 -                ownMap = addBoundProperty(ownMap, source, property);
    1.20 +                ownMap = addBoundProperty(ownMap, source, property, extensible);
    1.21              }
    1.22          }
    1.23  
    1.24 @@ -2731,9 +2732,9 @@
    1.25          }
    1.26  
    1.27          @Override
    1.28 -        protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property) {
    1.29 +        protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property, final boolean extensible) {
    1.30              // We override this method just to make it callable by Global
    1.31 -            return super.addBoundProperty(propMap, source, property);
    1.32 +            return super.addBoundProperty(propMap, source, property, extensible);
    1.33          }
    1.34  
    1.35          private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
     2.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jul 22 10:18:33 2015 +0200
     2.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Jul 13 20:09:14 2015 +0530
     2.3 @@ -287,9 +287,10 @@
     2.4       */
     2.5      public void addBoundProperties(final ScriptObject source, final Property[] properties) {
     2.6          PropertyMap newMap = this.getMap();
     2.7 +        final boolean extensible = newMap.isExtensible();
     2.8  
     2.9          for (final Property property : properties) {
    2.10 -            newMap = addBoundProperty(newMap, source, property);
    2.11 +            newMap = addBoundProperty(newMap, source, property, extensible);
    2.12          }
    2.13  
    2.14          this.setMap(newMap);
    2.15 @@ -302,13 +303,18 @@
    2.16       * @param propMap the property map
    2.17       * @param source the source object
    2.18       * @param property the property to be added
    2.19 +     * @param extensible whether the current object is extensible or not
    2.20       * @return the new property map
    2.21       */
    2.22 -    protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property) {
    2.23 +    protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property, final boolean extensible) {
    2.24          PropertyMap newMap = propMap;
    2.25          final String key = property.getKey();
    2.26          final Property oldProp = newMap.findProperty(key);
    2.27          if (oldProp == null) {
    2.28 +            if (! extensible) {
    2.29 +                throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
    2.30 +            }
    2.31 +
    2.32              if (property instanceof UserAccessorProperty) {
    2.33                  // Note: we copy accessor functions to this object which is semantically different from binding.
    2.34                  final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
    2.35 @@ -337,11 +343,15 @@
    2.36       */
    2.37      public void addBoundProperties(final Object source, final AccessorProperty[] properties) {
    2.38          PropertyMap newMap = this.getMap();
    2.39 +        final boolean extensible = newMap.isExtensible();
    2.40  
    2.41          for (final AccessorProperty property : properties) {
    2.42              final String key = property.getKey();
    2.43  
    2.44              if (newMap.findProperty(key) == null) {
    2.45 +                if (! extensible) {
    2.46 +                    throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
    2.47 +                }
    2.48                  newMap = newMap.addPropertyBind(property, source);
    2.49              }
    2.50          }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/script/basic/JDK-8130853.js	Mon Jul 13 20:09:14 2015 +0530
     3.3 @@ -0,0 +1,89 @@
     3.4 +/*
     3.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + * 
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + * 
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + * 
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + * 
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/**
    3.28 + * JDK-8130853: Non-extensible global is not handled property
    3.29 + *
    3.30 + * @test
    3.31 + * @run
    3.32 + */
    3.33 +
    3.34 +// don't allow extensions to global
    3.35 +Object.preventExtensions(this);
    3.36 +try {
    3.37 +    eval("var x = 34;");
    3.38 +    throw new Error("should have thrown TypeError");
    3.39 +} catch (e) {
    3.40 +    if (! (e instanceof TypeError)) {
    3.41 +        throw e;
    3.42 +    }
    3.43 +}
    3.44 +
    3.45 +try {
    3.46 +    eval("function func() {}");
    3.47 +    throw new Error("should have thrown TypeError");
    3.48 +} catch (e) {
    3.49 +    if (! (e instanceof TypeError)) {
    3.50 +        throw e;
    3.51 +    }
    3.52 +}
    3.53 +
    3.54 +function checkLoad(code) {
    3.55 +    try {
    3.56 +        load({ name: "test", script: code });
    3.57 +        throw new Error("should have thrown TypeError for load: " + code);
    3.58 +    } catch (e) {
    3.59 +        if (! (e instanceof TypeError)) {
    3.60 +            throw e;
    3.61 +        }
    3.62 +    }
    3.63 +}
    3.64 +
    3.65 +checkLoad("var y = 55");
    3.66 +checkLoad("function f() {}");
    3.67 +
    3.68 +// check script engine eval
    3.69 +var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
    3.70 +var e = new ScriptEngineManager().getEngineByName("nashorn");
    3.71 +var global = e.eval("this");
    3.72 +e.eval("Object.preventExtensions(this);");
    3.73 +try {
    3.74 +    e.eval("var myVar = 33;");
    3.75 +    throw new Error("should have thrown TypeError");
    3.76 +} catch (e) {
    3.77 +    if (! (e.cause.ecmaError instanceof global.TypeError)) {
    3.78 +        throw e;
    3.79 +    }
    3.80 +}
    3.81 +
    3.82 +// Object.bindProperties on arbitrary non-extensible object
    3.83 +var obj = {};
    3.84 +Object.preventExtensions(obj);
    3.85 +try {
    3.86 +    Object.bindProperties(obj, { foo: 434 });
    3.87 +    throw new Error("should have thrown TypeError");
    3.88 +} catch (e) {
    3.89 +    if (! (e instanceof TypeError)) {
    3.90 +        throw e;
    3.91 +    }
    3.92 +}

mercurial