Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8066932

__noSuchMethod__ binds to this-object without proper guard

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8u25
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b43
    • CPU:
      x86_64
    • OS:
      windows_7

      Backports

        Description

        FULL PRODUCT VERSION :
        java version "1.8.0_25"
        Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
        Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        If __noSuchMethod__ is used on a Prototype, it seems that the ScriptEngine executes the function with the first Object the script was called (ScriptEngien.eval). The second call to the ScriptEngine with invokeFunction the JavaScript object behaves like a singleton. I tested this with a JDK7 (Rhino) successfully, but on a JDK8 it did'nt work like expected.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Execute TestCase with JDK7, look for output
        2. Execute TestCase with JDK8 compare outputs

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        868385821 == 868385821
        675655832 == 675655832
        2001526735 == 2001526735
        1475988537 == 1475988537
        1355734862 == 1355734862
        ACTUAL -
        1073533248 == 1073533248
        576936864 != 1073533248
        1653844940 != 1073533248
        260840925 != 1073533248
        1891502635 != 1073533248

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import javax.script.Invocable;
        import javax.script.ScriptEngine;
        import javax.script.ScriptEngineManager;
        import javax.script.ScriptException;

        public class PrototypeTest {
            private static final String TEST_SCRIPT =
        "function proxyCall(realObj, mthName, args) {\r\n" +
        " var funcMap = {\r\n" +
        " 'arg0': function (obj, id, arg) {\r\n" +
        " return obj[id]();\r\n" +
        " }\r\n" +
        " };\r\n" +
        " var argType = 'arg' + args.length;\r\n" +
        " if (!(argType in funcMap)) {\r\n" +
        " var funcStr = 'function(obj, id, arg){return obj[id](';\r\n" +
        " for (var i = 0, len = args.length; i < len; i++) {\r\n" +
        " funcStr += 'arg[' + i + ']';\r\n" +
        " if ((i + 1) < len) {\r\n" +
        " funcStr += ',';\r\n" +
        " }\r\n" +
        " }\r\n" +
        " funcStr += ');}';\r\n" +
        " funcMap[argType] = eval(funcStr);\r\n" +
        " }\r\n" +
        " return funcMap[argType](realObj, mthName, args);\r\n" +
        "}\r\n" +
        "function Dummy(obj) {\r\n" +
        " this.myObj = obj;\r\n" +
        "}\r\n" +
        "Dummy.prototype.hashCodeFunc = function () {\r\n" +
        " return this.myObj.hashCode();\r\n" +
        "};\r\n" +
        "Dummy.prototype.__noSuchMethod__ = function (name, args) {\r\n" +
        " var callArgs;\r\n" +
        " if (arguments.length == 2 && Array.isArray(args)) {\r\n" +
        " callArgs = args;\r\n" +
        " } else {\r\n" +
        " callArgs = Array.prototype.slice.call(arguments, 1);\r\n" +
        " }\r\n" +
        " return proxyCall(this.myObj, name, callArgs);\r\n" +
        "};\r\n" +
        "function handle(obj) {\r\n" +
        " var dum = new Dummy(obj);\r\n" +
        " var hc1 = dum.hashCodeFunc();\r\n" +
        " var hc2 = dum.hashCode();\r\n" +
        " print(hc1 + (hc1 == hc2 ? ' == ' : ' != ') + hc2 + '\\r\\n');\r\n" +
        "}\r\n";

            public static void main(String[] args) {
                ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
                try {
                    se.eval(TEST_SCRIPT);
                    for(int i=0; i<5; i++) {
                        ((Invocable)se).invokeFunction("handle", new Object());
                    }
                } catch (ScriptException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
        }

        ---------- END SOURCE ----------

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                hannesw Hannes Wallnoefer
                Reporter:
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: