-
Bug
-
Resolution: Won't Fix
-
P3
-
8
-
x86
-
linux_redhat_6.0
FULL PRODUCT VERSION :
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) Client VM (build 25.40-b25, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Red Hat Enterprise Linux Server release 6.4 (Santiago)
A DESCRIPTION OF THE PROBLEM :
Behavior of the String object in Nashorn script engine is different for replace and split.
Though the object is java.lang.String the replace and split works like the javascript native String object.
REGRESSION. Last worked in version 8u40
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Create a script engine
- Execute a javascript with java.lang.String replace or split
- Expected behavior of replace method is to replace all the character sequence with replacement string
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
PQR-PQR-PQR
ACTUAL -
PQR-ABC-ABC
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;
public class TestJavascript {
public static void main(String[] args) throws Exception {
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptManager.getEngineByName("JavaScript");
Compilable jsCompile = (Compilable) scriptEngine;
CompiledScript cs = jsCompile.compile("java.lang.System.out.println(new java.lang.String(\"ABC-ABC-ABC\").replace(\"ABC\", \"PQR\"));");
ScriptContext sc = new SimpleScriptContext();
cs.eval(sc);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Change the Javascript prototype for replace and split with same implementation as in Java.
------------------------------------------------------------------------
String.prototype.replace = function(target, replacement) {
var cstring = new java.lang.String(this);
return Pattern.compile(target, Pattern.LITERAL).matcher(cstring).replaceAll(Matcher.quoteReplacement(replacement));
}
String.prototype.split = function(regex, limit) {
var cstring = new java.lang.String(this);
var StringArrayType = Java.type("java.lang.String[]")
var ch = 0;
if (((regex.length() == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0 &&
((ch - 'a') | ('z' - ch)) < 0 &&
((ch - 'A') | ('Z' - ch)) < 0)) &&
(ch < '\uD800' ||
ch > '\uDBFF')) {
var off = 0;
var next = 0;
var limited = limit > 0;
var list = new java.util.ArrayList();
while ((next = cstring.indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(cstring.substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(cstring.substring(off, cstring.length()));
off = cstring.length();
break;
}
}
// If no match was found, return this
if (off == 0) {
var ret = new StringArrayType(1);
ret[0] = cstring;
return ret;
}
// Add remaining segment
if (!limited || list.size() < limit) {
list.add(cstring.substring(off, cstring.length()));
}
// Construct result
var resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
var result = new StringArrayType(resultSize);
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(cstring, limit);
}
SUPPORT :
YES
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) Client VM (build 25.40-b25, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Red Hat Enterprise Linux Server release 6.4 (Santiago)
A DESCRIPTION OF THE PROBLEM :
Behavior of the String object in Nashorn script engine is different for replace and split.
Though the object is java.lang.String the replace and split works like the javascript native String object.
REGRESSION. Last worked in version 8u40
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Create a script engine
- Execute a javascript with java.lang.String replace or split
- Expected behavior of replace method is to replace all the character sequence with replacement string
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
PQR-PQR-PQR
ACTUAL -
PQR-ABC-ABC
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;
public class TestJavascript {
public static void main(String[] args) throws Exception {
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptManager.getEngineByName("JavaScript");
Compilable jsCompile = (Compilable) scriptEngine;
CompiledScript cs = jsCompile.compile("java.lang.System.out.println(new java.lang.String(\"ABC-ABC-ABC\").replace(\"ABC\", \"PQR\"));");
ScriptContext sc = new SimpleScriptContext();
cs.eval(sc);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Change the Javascript prototype for replace and split with same implementation as in Java.
------------------------------------------------------------------------
String.prototype.replace = function(target, replacement) {
var cstring = new java.lang.String(this);
return Pattern.compile(target, Pattern.LITERAL).matcher(cstring).replaceAll(Matcher.quoteReplacement(replacement));
}
String.prototype.split = function(regex, limit) {
var cstring = new java.lang.String(this);
var StringArrayType = Java.type("java.lang.String[]")
var ch = 0;
if (((regex.length() == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0 &&
((ch - 'a') | ('z' - ch)) < 0 &&
((ch - 'A') | ('Z' - ch)) < 0)) &&
(ch < '\uD800' ||
ch > '\uDBFF')) {
var off = 0;
var next = 0;
var limited = limit > 0;
var list = new java.util.ArrayList();
while ((next = cstring.indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(cstring.substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(cstring.substring(off, cstring.length()));
off = cstring.length();
break;
}
}
// If no match was found, return this
if (off == 0) {
var ret = new StringArrayType(1);
ret[0] = cstring;
return ret;
}
// Add remaining segment
if (!limited || list.size() < limit) {
list.add(cstring.substring(off, cstring.length()));
}
// Construct result
var resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
var result = new StringArrayType(resultSize);
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(cstring, limit);
}
SUPPORT :
YES