Skip to content

Commit 110216e

Browse files
committed
Add explicit type check to UpdateStrategy.convert()
When using the DefaultConverter, type erasure may occur, where the "convert" method returns an object of type S, but treats it as type D. The conversion must fail early in such a case, in order to prevent obscure error messages when passing the value to successive methods. Closes #3008
1 parent b141132 commit 110216e

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/UpdateStrategy.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,12 @@ protected IStatus logErrorWhileSettingValue(Exception ex) {
652652
public D convert(S value) {
653653
if (converter != null) {
654654
try {
655-
return converter.convert(value);
655+
// Explicit cast necessary due to potential type erasure
656+
D result = converter.convert(value);
657+
if (converter.getToType() instanceof Class<?> clazz) {
658+
return (D) clazz.cast(result);
659+
}
660+
return result;
656661
} catch (Exception ex) {
657662
Policy.getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex));
658663
throw ex;

tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/UpdateStrategyTest.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2007 IBM Corporation and others.
2+
* Copyright (c) 2007, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,11 +16,15 @@
1616

1717
import static org.junit.Assert.assertEquals;
1818
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.assertThrows;
1920
import static org.junit.Assert.assertTrue;
2021

2122
import java.math.BigDecimal;
2223
import java.math.BigInteger;
2324
import java.util.Date;
25+
import java.util.HashSet;
26+
import java.util.List;
27+
import java.util.Set;
2428

2529
import org.eclipse.core.databinding.UpdateValueStrategy;
2630
import org.eclipse.core.databinding.conversion.IConverter;
@@ -354,4 +358,16 @@ public UpdateValueStrategy<S, D> setConverter(IConverter<? super S, ? extends D>
354358
return super.setConverter(converter);
355359
}
356360
}
361+
362+
@Test
363+
public void testDefaultConverterWithTypeErasure() {
364+
WritableValue<Set<?>> source = WritableValue.withValueType(Set.class);
365+
WritableValue<List<?>> destination = WritableValue.withValueType(List.class);
366+
367+
UpdateStrategyStub<Set<?>, List<?>> strategy = new UpdateStrategyStub<>();
368+
strategy.fillDefaults(source, destination);
369+
370+
RuntimeException ex = assertThrows(RuntimeException.class, () -> strategy.convert(new HashSet<>()));
371+
assertTrue("Type erasure was missed", ex.getCause() instanceof ClassCastException);
372+
}
357373
}

0 commit comments

Comments
 (0)