oracle / graaljs

GraalJS – A high-performance, ECMAScript compliant, and embeddable JavaScript runtime for Java
https://www.graalvm.org/javascript/
Universal Permissive License v1.0
1.81k stars 190 forks source link

String.prototype.repeat has no limits #697

Open naijun0403 opened 1 year ago

naijun0403 commented 1 year ago

Enviroment

os: WSL2 Ubuntu 22.04 LTS (Windows 11) GraalJS Version: 22.3.0

(I know there was a new release of GraalJS a while ago, but I searched for related issues and it doesn't seem to have been resolved, so I think it will probably be reproduced in the new release as well.)

VM: GraalVM CE 22.3.0

Bug reimplementation

excuting this script

'\u200b'.repeat(1000000000)

expected result

RangeError: Invalid string length

in nodejs 16.17.1

actual result

org.graalvm.polyglot.PolyglotException: java.lang.NegativeArraySizeException: -1294967296

iamstolis commented 1 year ago

Thank you for the report. I am able to reproduce the mentioned exception:

$ mx js
> '\u200b'.repeat(1000000000)
org.graalvm.polyglot.PolyglotException: java.lang.NegativeArraySizeException: -1294967296
    at java.base/java.lang.String.encodeUTF8_UTF16(String.java:1286)
    at java.base/java.lang.String.encodeUTF8(String.java:1262)
    at java.base/java.lang.String.encode(String.java:825)
    at java.base/java.lang.String.getBytes(String.java:1786)
    at com.oracle.truffle.polyglot.PolyglotContextImpl.printResult(PolyglotContextImpl.java:1524)
    at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:1491)
    at com.oracle.truffle.polyglot.PolyglotContextDispatch.eval(PolyglotContextDispatch.java:63)
    at org.graalvm.polyglot.Context.eval(Context.java:401)
    at com.oracle.truffle.js.shell.JSLauncher.runREPL(JSLauncher.java:394)
    at com.oracle.truffle.js.shell.JSLauncher.executeScripts(JSLauncher.java:343)
    at com.oracle.truffle.js.shell.JSLauncher.launch(JSLauncher.java:88)
    ...

It is expected that '\u200b'.repeat(1000000000) expression does not result in RangeError in graal-js. Our default limit of string length is 1073741799 (which used to be the string length limit of V8/Node.js). The current string length limit of V8/Node.js is 536870888. That's why you see RangeError error there. graal-js produces the same result when you use this limit:

$ mx js --experimental-options --js.string-length-limit=536870888
> '\u200b'.repeat(1000000000)
RangeError: Invalid string length
    at <js> :program(<shell>:1:1:0-26)

Of course, the we should not throw NegativeArraySizeException. In fact, this exception is not an issue in graal-js itself. It is caused by the code in truffle that attempts to print the result of the evaluated expression.