# HG changeset patch # User Doug Simon # Date 1391724846 -3600 # Node ID 45f9dbb9398883b910fe7e7b81edba7b62b5473a # Parent d9aad522d3556e08b8999bf987e6805d5f5c17e9 modified Kind.format() to avoid calling any user code (JBS:GRAAL-14) diff -r d9aad522d355 -r 45f9dbb93988 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Thu Feb 06 22:47:41 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Thu Feb 06 23:14:06 2014 +0100 @@ -255,19 +255,30 @@ /** * Marker interface for types that should be {@linkplain Kind#format(Object) formatted} with - * their {@link Object#toString()} value. + * their {@link Object#toString()} value. Calling {@link Object#toString()} on other objects + * poses a security risk because it can potentially call user code. */ public interface FormatWithToString { } /** + * Classes for which invoking {@link Object#toString()} does not run user code. + */ + private static boolean isToStringSafe(Class c) { + return c == Boolean.class || c == Byte.class || c == Character.class || c == Short.class || c == Integer.class || c == Float.class || c == Long.class || c == Double.class; + } + + /** * Gets a formatted string for a given value of this kind. * * @param value a value of this kind * @return a formatted string for {@code value} based on this kind */ public String format(Object value) { - if (this == Kind.Object) { + if (isPrimitive()) { + assert isToStringSafe(value.getClass()); + return value.toString(); + } else { if (value == null) { return "null"; } else { @@ -280,18 +291,20 @@ } } else if (value instanceof JavaType) { return "JavaType:" + MetaUtil.toJavaName((JavaType) value); - } else if (value instanceof Enum || value instanceof FormatWithToString || value instanceof Number) { + } else if (value instanceof Enum) { + return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); + } else if (value instanceof FormatWithToString) { return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value); } else if (value instanceof Class) { return "Class:" + ((Class) value).getName(); + } else if (isToStringSafe(value.getClass())) { + return value.toString(); } else if (value.getClass().isArray()) { return formatArray(value); } else { return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value); } } - } else { - return value.toString(); } }