If you think a bug might affect users in the 57 release, please set the correct tracking and status flags for Release Management.

rhino bombs -- StackOverflowError on exception in toString

UNCONFIRMED
Unassigned

Status

Rhino
Core
--
critical
UNCONFIRMED
8 years ago
4 years ago

People

(Reporter: Jared Forsyth, Unassigned)

Tracking

Details

(Reporter)

Description

8 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.29 Safari/533.4
Build Identifier: Rhino 1.7 release 2 2010 01 20

I've included a simple example which throws an exception in an object's toString function, causing a StackOverflowError

Reproducible: Always

Steps to Reproduce:
1. run "var a={};a.toString=function(){return a.b();};print(a)" in rhino
2. or type "echo 'a={};a.toString=function(){return a.b();};print(a);'|rhino" into the cmd-line

here's the sequence that loops, causing the overflow

	at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:724)
	at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3741)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2247)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2214)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3143)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:760)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:700)
Actual Results:  
Rhino 1.7 release 2 2010 01 20
js> a={};a.toString=function(){return a.b();};print(a);
java.lang.StackOverflowError
	at org.mozilla.javascript.ScriptableObject.getSlot(ScriptableObject.java:2149)
	at org.mozilla.javascript.ScriptableObject.getImpl(ScriptableObject.java:2000)
	at org.mozilla.javascript.ScriptableObject.get(ScriptableObject.java:287)
	at org.mozilla.javascript.IdScriptableObject.get(IdScriptableObject.java:387)
	at org.mozilla.javascript.ImporterTopLevel.get(ImporterTopLevel.java:131)
	at org.mozilla.javascript.ScriptableObject.getProperty(ScriptableObject.java:1617)
	at org.mozilla.javascript.ScriptRuntime.topScopeName(ScriptRuntime.java:1788)
	at org.mozilla.javascript.ScriptRuntime.name(ScriptRuntime.java:1690)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3410)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:760)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:700)
	at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:724)
	at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3741)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2247)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2214)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3143)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:760)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:700)
	at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:724)
	at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3741)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2247)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2214)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3143)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:760)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:700)
	at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:724)
	at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3741)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2247)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2214)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3143)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:760)
	at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:700)
	at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:724)
	at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3741)
	at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2247)
js: exception from uncaught JavaScript throw: java.lang.StackOverflowError
js> 

Expected Results:  
js: "<stdin>", line 4: uncaught JavaScript runtime exception: TypeError: Cannot find function b in object [exception in object's toString].
        at <stdin>:4
        at <stdin>:5

Comment 1

6 years ago
This appears to be a valid bug. I can confirm I reproduced it.

The below change to ScriptRuntime.java worked for me to fix this. There may well be better ways.


......
    public static RuntimeException notFunctionError(Object obj, Object value,
            String propertyName)
    {
        // Use obj and value for better error reporting
    	// check stack first for infinite recursion
    	String objString = "[exception in object's toString]";
        CharArrayWriter writer = new CharArrayWriter();
        RuntimeException re = new RuntimeException();
        re.printStackTrace(new PrintWriter(writer));
        String s = writer.toString();
    	if(0 == s.indexOf("notFunctionError")){
            objString = toString(obj);
    	}
    	
        if (obj instanceof NativeFunction) {
....

Comment 2

6 years ago
hmmm... should have tested it a little better. need to see 2 occurrances in the stack...

        
        int lastIndex = 0;
        int count =0;

        while(lastIndex != -1){

               lastIndex = s.indexOf("notFunctionError",lastIndex);

               if( lastIndex != -1){
                     count ++;
                     lastIndex++;
              }
        }
        
    	if( count<2){
            objString = toString(obj);
    	}
You need to log in before you can comment on or make changes to this bug.