-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8292317: Missing null check for Iterator.forEachRemaining implementations #11154
Conversation
👋 Welcome back jpai! A progress list of the required criteria for merging this PR into |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@jaikiran This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 103 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
Assert.assertThrows(NullPointerException.class, () -> it.forEachRemaining(null)); | ||
// verify the iterator didn't advance | ||
Assert.assertTrue("Iterator unexpectedly doesn't have any entry", it.hasNext()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The checks in Collections.java look good.
The tests can be simplified, I think. The reproducers in the original bug report wrap an empty map in either an unmodifiable map or a checked map, so you could just test them with entrySet().iterator().forEachRemaining(null). Those cases do nothing in the current JDK when they indeed should throw NPE. Probably just test for NPE thrown/not-thrown instead of trying to ascertain the position of the iterator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Stuart, I have now updated the PR to simplify the test as suggested. New test methods continue to fail without the source change and pass with this fix.
tier1, tier2, tier3 and java_util tests in JCK have passed with this change. |
Objects.requireNonNull(action); | ||
i.forEachRemaining(entryConsumer(action)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As pointed out in the bug report description, it might be better to add the null
check to entryConsumer
. That would avoid code duplication for the null
checks for all the current callers of entryConsumer
.
(This comment only applies here; for CheckedEntrySet
below this does not work because it does not call entryConsumer
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @Marcono1234, I prefer doing it earliest in the top level method (which specifies the contract) instead of doing it in an internal method that this method calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated tests look good, thanks.
Thank you everyone for the reviews and the suggestions. |
/integrate |
Going to push as commit 906f1ca.
Your commit was automatically rebased without conflicts. |
Can I please get a review of this change which proposes to fix https://bugs.openjdk.org/browse/JDK-8292317?
The
java.util.Iterator
has aforEachRemaining(Consumer<? super E> action)
method. As per its contract, the implementations are expected to throw aNullPointerException
if the passedaction
isnull
.java.util.Collections
has a couple of places where it wraps the passedaction
into another and passes that wrappedaction
to the underlyingjava.util.Iterator
's defaultforEachRemaining
implementation which is:Since the passed
action
is now a non-null wrapper, the implementation goes ahead and advances the iterator to the next entry and invokes on the non-nullaction
to carry out its action. That non-null wrapper action then calls thenull
user passed action and runs into an expectedNullPointerException
. However, at this point the iterator has already advanced and that is what the bug is.The commit in this PR introduces a trivial null check on the
action
very early in the call even before wrapping such anaction
. This prevents any further logic to execute ifaction
is null.New test methods have been added to the existing test class
test/jdk/java/util/Collections/DelegatingIteratorForEachRemaining.java
. This test class was introduced in https://bugs.openjdk.org/browse/JDK-8205184 where this delegation logic was added for theforEachRemaining
methods. These new test methods reproduce the failure and verify the fix.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/11154/head:pull/11154
$ git checkout pull/11154
Update a local copy of the PR:
$ git checkout pull/11154
$ git pull https://git.openjdk.org/jdk pull/11154/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 11154
View PR using the GUI difftool:
$ git pr show -t 11154
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/11154.diff