[
https://issues.apache.org/jira/browse/CAMEL-26437?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18136022#comment-18136022
]
Claus Ibsen commented on CAMEL-26437:
-------------------------------------
Fixed via https://github.com/apache/camel/pull/28784
_Claude Code on behalf of Claus Ibsen_
> camel-util - FilterIterator.remove after a failed next removes an element
> that next never returned
> --------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26437
> URL: https://issues.apache.org/jira/browse/CAMEL-26437
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Minor
> Fix For: 4.24.0
>
>
> Follow-up of CAMEL-26290 (apache/camel#28643), which made
> {{FilterIterator.remove()}} throw {{IllegalStateException}} after a
> {{hasNext()}} look-ahead, because the look-ahead moves the wrapped iterator
> past the element {{next()}} returned.
> {{next()}} looks ahead in the same way when it has no element ready:
> {{checkNext()}} calls {{it.next()}} on the wrapped iterator until the filter
> accepts an element. If that does not end with an accepted element, {{next()}}
> fails, but the permission to remove from the previous successful {{next()}}
> is kept, while the wrapped iterator is now on another element. A {{remove()}}
> then removes that element, which {{next()}} never returned:
> {code:java}
> List<Integer> list = new ArrayList<>(List.of(1, 2));
> FilterIterator<Integer> it = new FilterIterator<>(list.iterator(), n -> n ==
> 1);
> it.next(); // 1
> it.next(); // looks at 2, rejects it, throws NoSuchElementException
> it.remove(); // removes 2; list is now [1]
> {code}
> The same happens when the filter throws while it looks at the next element,
> and when the elements left are null (they are skipped). The javadoc of
> {{remove()}} says it removes the last element returned by {{next()}}.
> Found by an OpenJML/JML verification pilot of the {{FilterIterator}} contract
> (the removal-safety condition failed on the original source and holds with
> the change below), then reproduced with plain JUnit tests.
> *Proposal*
> * In {{checkNext()}}, set {{canRemove = false}} right before each
> {{it.next()}}: once the wrapped iterator moves, the element returned last can
> no longer be removed. A successful {{next()}} sets it again. A {{next()}}
> that fails at the end of the wrapped iterator, without moving it, keeps the
> element returned before removable (as a list iterator does).
> * Tests: {{NoSuchElementException}} after a rejected tail, a throwing filter,
> a skipped null tail, and controls (end of the wrapped iterator, {{hasNext()}}
> before the failed {{next()}}).
> * Fold one paragraph into the existing 4.24 upgrade guide entry of
> CAMEL-26290.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)