[ 
https://issues.apache.org/jira/browse/CAMEL-26437?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-26437 started by shashank.
----------------------------------------
> 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
>
> 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)

Reply via email to