diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java index b965f25bf0e..a03a7b244eb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java @@ -30,8 +30,14 @@ public class Utility { } public static char StringTochar(final String value) { + if (value == null) { + throw new ClassCastException("cannot cast " + + "null " + String.class.getCanonicalName() + " to " + char.class.getCanonicalName()); + } + if (value.length() != 1) { - throw new ClassCastException("Cannot cast [String] with length greater than one to [char]."); + throw new ClassCastException("cannot cast " + + String.class.getCanonicalName() + " with length not equal to one to " + char.class.getCanonicalName()); } return value.charAt(0); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StandardCastTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StandardCastTests.java index 604e20ad6f9..739d9d021a4 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StandardCastTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StandardCastTests.java @@ -545,4 +545,100 @@ public class StandardCastTests extends ScriptTestCase { expectScriptThrows(ClassCastException.class, () -> exec("Number o = new ArrayList(); ArrayList b = o;")); expectScriptThrows(ClassCastException.class, () -> exec("Number o = new ArrayList(); ArrayList b = (ArrayList)o;")); } + + public void testStringCasts() { + exec("String o = 'string'; Object n = o;"); + exec("String o = null; Object n = o;"); + exec("String o = 'string'; Object n = (Object)o;"); + exec("String o = null; Object n = (Object)o;"); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Number n = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Number n = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Number n = (String)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Number n = (String)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; boolean b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; boolean b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; boolean b = (boolean)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; boolean b = (boolean)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; byte b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; byte b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; byte b = (byte)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; byte b = (byte)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; short b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; short b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; short b = (short)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; short b = (short)o;")); + + assertEquals('s', exec("String s = 's'; (char)s")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; char b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; char b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; char b = (char)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; char b = (char)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; int b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; int b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; int b = (int)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; int b = (int)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; long b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; long b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; long b = (long)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; long b = (long)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; float b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; float b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; float b = (float)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; float b = (float)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; double b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; double b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; double b = (double)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; double b = (double)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Boolean b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Boolean b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Boolean b = (Boolean)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Boolean b = (Boolean)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Byte b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Byte b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Byte b = (Byte)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Byte b = (Byte)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Short b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Short b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Short b = (Short)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Short b = (Short)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Character b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Character b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Character b = (Character)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Character b = (Character)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Integer b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Integer b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Integer b = (Integer)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Integer b = (Integer)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Long b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Long b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Long b = (Long)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Long b = (Long)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Float b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Float b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Float b = (Float)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Float b = (Float)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Double b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Double b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; Double b = (Double)o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = null; Double b = (Double)o;")); + + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; ArrayList b = o;")); + expectScriptThrows(ClassCastException.class, () -> exec("String o = 'string'; ArrayList b = (ArrayList)o;")); + } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java index c73d6c2071a..31870b9125c 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java @@ -170,22 +170,22 @@ public class StringTests extends ScriptTestCase { ClassCastException expected = expectScriptThrows(ClassCastException.class, false, () -> { assertEquals("cc", exec("return (String)(char)\"cc\"")); }); - assertTrue(expected.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); + assertTrue(expected.getMessage().contains("cannot cast java.lang.String with length not equal to one to char")); expected = expectScriptThrows(ClassCastException.class, false, () -> { assertEquals("cc", exec("return (String)(char)'cc'")); }); - assertTrue(expected.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); + assertTrue(expected.getMessage().contains("cannot cast java.lang.String with length not equal to one to char")); expected = expectScriptThrows(ClassCastException.class, () -> { assertEquals('c', exec("String s = \"cc\"; (char)s")); }); - assertTrue(expected.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); + assertTrue(expected.getMessage().contains("cannot cast java.lang.String with length not equal to one to char")); expected = expectScriptThrows(ClassCastException.class, () -> { assertEquals('c', exec("String s = 'cc'; (char)s")); }); - assertTrue(expected.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); + assertTrue(expected.getMessage().contains("cannot cast java.lang.String with length not equal to one to char")); } public void testDefConcat() {