Skip to content

Commit 5c160d2

Browse files
committed
Ensure that invalid strings cannot be converted
1 parent bd40f05 commit 5c160d2

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/main/java/org/scijava/convert/StringToNumberConverter.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class StringToNumberConverter extends AbstractConverter<String, Number> {
1919
@SuppressWarnings("unchecked")
2020
public <T> T convert(Object src, Class<T> dest) {
2121
// ensure type is well-behaved, rather than a primitive type
22-
Class<T> saneDest = Types.box(dest);
22+
Class<T> saneDest = sane(dest);
2323
if (!(src instanceof String)) throw new IllegalArgumentException(
2424
"Expected src to be a String but got a " + src.getClass());
2525
if (!(Number.class.isAssignableFrom(saneDest)))
@@ -33,7 +33,6 @@ public <T> T convert(Object src, Class<T> dest) {
3333
if (saneDest == Long.class) return (T) new Long(srcString);
3434
if (saneDest == Float.class) return (T) new Float(srcString);
3535
if (saneDest == Double.class) return (T) new Double(srcString);
36-
if (saneDest == Number.class) return (T) new Double(srcString);
3736
else throw new IllegalArgumentException("Unknown destination type: " +
3837
saneDest);
3938
}
@@ -51,6 +50,22 @@ public Class<String> getInputType() {
5150
@Override
5251
public boolean canConvert(Object src, Class<?> dest) {
5352
if (!Types.isAssignable(src.getClass(), String.class)) return false;
54-
return Types.isAssignable(Types.box(dest), Number.class);
53+
// The only way to know if the conversion is valid is to actually do it.
54+
try {
55+
String srcString = (String) src;
56+
sane(dest).getConstructor(String.class).newInstance(srcString);
57+
return true;
58+
}
59+
catch (Exception e) {
60+
return false;
61+
}
62+
}
63+
64+
// -- Helper functionality -- //
65+
66+
@SuppressWarnings("unchecked")
67+
private <T> Class<T> sane(Class<T> c) {
68+
if (c == Number.class) return (Class<T>) Double.class;
69+
return Types.box(c);
5570
}
5671
}

src/test/java/org/scijava/convert/StringToNumberConverterTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,12 @@ public void stringToNumberTest() {
109109
Assert.assertTrue(conv.canConvert(s, Number.class));
110110
Assert.assertEquals(0d, conv.convert(s, Number.class));
111111
}
112+
113+
@Test
114+
public void invalidStringToNumberTest() {
115+
String s = "invalid";
116+
Assert.assertFalse(conv.canConvert(s, Number.class));
117+
Assert.assertThrows(IllegalArgumentException.class, () -> conv.convert(s,
118+
Number.class));
119+
}
112120
}

0 commit comments

Comments
 (0)