[
https://issues.apache.org/jira/browse/COLLECTIONS-890?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18090189#comment-18090189
]
Gary D. Gregory commented on COLLECTIONS-890:
---------------------------------------------
[~rickydong]
Please see my comments in the PR.
TY.
> TransformIterator documents null transformers as pass-through, but next()
> throws NullPointerException
> -----------------------------------------------------------------------------------------------------
>
> Key: COLLECTIONS-890
> URL: https://issues.apache.org/jira/browse/COLLECTIONS-890
> Project: Commons Collections
> Issue Type: Bug
> Components: Iterator
> Reporter: Ruiqi Dong
> Priority: Minor
>
> *Summary*
> `TransformIterator` documents the same contract in three places:
> - constructor: null transformer means elements will not be transformed
> - `next()`: null transformer means the original element is returned directly
> - `setTransformer(...)`: null transformer is a no-op transformer
> The implementation does not honor that contract. `next()` always calls
> `transformer.apply(...)`, so a null transformer causes an immediate
> `NullPointerException`.
>
> *Affected code*
> File:
> `src/main/java/org/apache/commons/collections4/iterators/TransformIterator.java`
> {code:java}
> public TransformIterator(final Iterator<? extends I> iterator,
> final Transformer<? super I, ? extends O>
> transformer) {
> this.iterator = iterator;
> this.transformer = transformer;
> }
> @Override
> public O next() {
> return transform(iterator.next());
> }
> protected O transform(final I source) {
> return transformer.apply(source);
> } {code}
> The same class also states:
> {code:java}
> // constructor Javadoc
> // If the given transformer is null, then objects will not be transformed.
> // next() Javadoc
> // If the transformer is null, no transformation occurs and the object
> // from the iterator is returned directly.
> // setTransformer(...) Javadoc
> // A null transformer is a no-op transformer. {code}
> *Reproducer*
> Add the following test to
> `src/test/java/org/apache/commons/collections4/iterators/TransformIteratorTest.java`:
> {code:java}
> @Test
> void testNullTransformerActsAsPassThrough() {
> final TransformIterator<Integer, Integer> iterator =
> new TransformIterator<>(Arrays.asList(1, 2).iterator(), null);
> assertEquals(Integer.valueOf(1), iterator.next());
> assertEquals(Integer.valueOf(2), iterator.next());
> } {code}
> Run:
> {code:java}
> mvn -q
> -Dtest=org.apache.commons.collections4.iterators.TransformIteratorTest#testNullTransformerActsAsPassThrough
> test {code}
> *Observed behavior*
> {code:java}
> java.lang.NullPointerException:
> Cannot invoke "org.apache.commons.collections4.Transformer.apply(Object)"
> because "this.transformer" is null {code}
> *Expected behavior*
> When the transformer is null, the iterator should behave as an identity
> transform and return the original elements unchanged.
> This is not just an undocumented corner case. The public Javadoc explicitly
> promises null-as-pass-through behavior, but the implementation
> unconditionally dereferences the transformer. Callers following the
> documented contract get a runtime failure instead of the advertised semantics.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)