The patch is attached.
Thanks, Tigran. ----- Original Message ----- > From: "Weijun Wang" <weijun.w...@oracle.com> > To: "Tigran Mkrtchyan" <tigran.mkrtch...@desy.de> > Cc: "security-dev" <security-dev@openjdk.java.net> > Sent: Friday, April 24, 2020 4:21:27 PM > Subject: Re: NPE is used in javax.security.auth.Subject for flowcontrol > You can send me a patch and I can sponsor it. > > Thanks, > Max > >> On Apr 24, 2020, at 9:54 PM, Mkrtchyan, Tigran <tigran.mkrtch...@desy.de> >> wrote: >> >> Hi Max, >> >> Do you want me to go though official contribution (I already have signed OCA >> for >> glassfish) or >> someone from oracle team will take care about it? >> >> Thanks, >> Tigran. >> >> ----- Original Message ----- >>> From: "Weijun Wang" <weijun.w...@oracle.com> >>> To: "Tigran Mkrtchyan" <tigran.mkrtch...@desy.de> >>> Cc: "security-dev" <security-dev@openjdk.java.net> >>> Sent: Friday, April 24, 2020 3:29:02 PM >>> Subject: Re: NPE is used in javax.security.auth.Subject for flowcontrol >> >>> Hi Tigran, >>> >>> I read "Collection.html#optional-restrictions" carefully, and yes you're >>> correct. Sorry for my ignorance. >>> >>> This method is called quite a lot. It might be worth an enhancement. >>> >>> Thanks, >>> Max >>> >>>> On Apr 24, 2020, at 9:00 PM, Mkrtchyan, Tigran <tigran.mkrtch...@desy.de> >>>> wrote: >>>> >>>> >>>> >>>> Here is the benchmark results: >>>> >>>> Benchmark Mode Cnt Score Error Units >>>> SubjectBenchmark.jdkSubject thrpt 20 473086.025 ± 7661.215 ops/s >>>> SubjectBenchmark.patchedSubject thrpt 20 2529016.530 ± 50982.465 ops/s >>>> >>>> On a one hand, patched version has 5x higher throughput. However, on an >>>> other >>>> hand >>>> the throughput of the original code is sufficient for any real >>>> application. The >>>> benchmark code is attached. >>>> >>>> Sorry for the noise. Should have done benchmarks before trying to optimize >>>> it. >>>> >>>> Tigran. >>>> >>>> ----- Original Message ----- >>>>> From: "Tigran Mkrtchyan" <tigran.mkrtch...@desy.de> >>>>> To: "Weijun Wang" <weijun.w...@oracle.com> >>>>> Cc: "security-dev" <security-dev@openjdk.java.net> >>>>> Sent: Friday, April 24, 2020 12:50:03 PM >>>>> Subject: Re: NPE is used in javax.security.auth.Subject for flowcontrol >>>> >>>>> I read it differently: >>>>> >>>>> Attempting to query the presence of an ineligible element may throw an >>>>> exception, or it may simply return false; some implementations >>>>> will exhibit the former behavior and some will exhibit the latter. >>>>> >>>>> Implementation might thrown an exception or return false, but sill don't >>>>> allow >>>>> null values. >>>>> >>>>> ... would not result in the insertion of an ineligible element into the >>>>> collection may throw an exception or it may >>>>> succeed, at the option of the implementation. >>>>> >>>>> >>>>> For example, TreeSet throws NPE depending on Comparator. >>>>> >>>>> Well, I understand, this is a corner case that possibly not worth to >>>>> optimize. >>>>> Let me write >>>>> a benchmark to see how much difference it makes. >>>>> >>>>> Tigran. >>>>> >>>>> >>>>> ----- Original Message ----- >>>>>> From: "Weijun Wang" <weijun.w...@oracle.com> >>>>>> To: "Tigran Mkrtchyan" <tigran.mkrtch...@desy.de> >>>>>> Cc: "security-dev" <security-dev@openjdk.java.net> >>>>>> Sent: Friday, April 24, 2020 12:23:48 PM >>>>>> Subject: Re: NPE is used in javax.security.auth.Subject for flowcontrol >>>>> >>>>>> My understanding is by optional you have 2 options while designing the >>>>>> Set: >>>>>> >>>>>> 1. Allow null >>>>>> >>>>>> 2. Not allow null >>>>>> >>>>>> Now that SecureSet has chosen the 2nd way, it is now in the "this set >>>>>> does not >>>>>> permit null elements" category and therefore it should "@throws >>>>>> NullPointerException if the specified element is null". >>>>>> >>>>>> --Max >>>>>> >>>>>>> On Apr 24, 2020, at 6:13 PM, Mkrtchyan, Tigran >>>>>>> <tigran.mkrtch...@desy.de> wrote: >>>>>>> >>>>>>> Hi Max, >>>>>>> >>>>>>> that's right, but java doc as well mentions that this exception is >>>>>>> *optional*, >>>>>>> and has a corresponding note: >>>>>>> >>>>>>> Some collection implementations have restrictions on the elements that >>>>>>> they may >>>>>>> contain. For example, some implementations prohibit null elements, and >>>>>>> some >>>>>>> have restrictions on the types of their elements. Attempting to add an >>>>>>> ineligible element throws an unchecked exception, typically >>>>>>> NullPointerException or ClassCastException. Attempting to query the >>>>>>> presence of >>>>>>> an ineligible element may throw an exception, or it may simply return >>>>>>> false; >>>>>>> some implementations will exhibit the former behavior and some will >>>>>>> exhibit the >>>>>>> latter. More generally, attempting an operation on an ineligible >>>>>>> element whose >>>>>>> completion would not result in the insertion of an ineligible element >>>>>>> into the >>>>>>> collection may throw an exception or it may succeed, at the option of >>>>>>> the >>>>>>> implementation. Such exceptions are marked as "optional" in the >>>>>>> specification >>>>>>> for this interface. >>>>>>> >>>>>>> Thus, returning *false* is justified and spec compliant. >>>>>>> >>>>>>> >>>>>>> Thanks, >>>>>>> Tigran. >>>>>>> >>>>>>> >>>>>>> ----- Original Message ----- >>>>>>>> From: "Weijun Wang" <weijun.w...@oracle.com> >>>>>>>> To: "Tigran Mkrtchyan" <tigran.mkrtch...@desy.de> >>>>>>>> Cc: "security-dev" <security-dev@openjdk.java.net> >>>>>>>> Sent: Friday, April 24, 2020 11:42:41 AM >>>>>>>> Subject: Re: NPE is used in javax.security.auth.Subject for flowcontrol >>>>>>> >>>>>>>> Hi Tigran, >>>>>>>> >>>>>>>> In java.util.Set, we have: >>>>>>>> >>>>>>>> * @throws NullPointerException if the specified element is null and >>>>>>>> this >>>>>>>> * set does not permit null elements >>>>>>>> * (<a href="Collection.html#optional-restrictions">optional</a>) >>>>>>>> */ >>>>>>>> boolean contains(Object o); >>>>>>>> >>>>>>>> As an implementation, SecureSet must follow the spec to throw an NPE. >>>>>>>> If it >>>>>>>> returns null, some unexpected thing might happen when the contains() >>>>>>>> method is >>>>>>>> called somewhere else. >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Max >>>>>>>> >>>>>>>>> On Apr 24, 2020, at 4:21 PM, Mkrtchyan, Tigran >>>>>>>>> <tigran.mkrtch...@desy.de> wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> Dear Java-SE security developers, >>>>>>>>> >>>>>>>>> >>>>>>>>> Imagine a following code: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Subject s1 = ... ; >>>>>>>>> >>>>>>>>> Subject s2 = ... ; >>>>>>>>> >>>>>>>>> >>>>>>>>> s2.getPrincipals().addAll(s1.getPrincipals()); >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> The Subject's SecureSet.addAll checks that provided Set doesn't >>>>>>>>> contains 'null' >>>>>>>>> values >>>>>>>>> by calling collectionNullClean, which calls SecureSet#contains: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> try { >>>>>>>>> hasNullElements = coll.contains(null); >>>>>>>>> } catch (NullPointerException npe) { >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> The SecureSet#contains itself checks for 'null' values, the NPE is >>>>>>>>> always >>>>>>>>> generated. >>>>>>>>> >>>>>>>>> This as introduced by commit e680ab7f208e >>>>>>>>> >>>>>>>>> https://hg.openjdk.java.net/jdk/jdk/diff/e680ab7f208e/jdk/src/share/classes/javax/security/auth/Subject.java >>>>>>>>> >>>>>>>>> >>>>>>>>> As SecureSet doesn't allow null values, it will be much simpler to >>>>>>>>> return false >>>>>>>>> right away: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> public boolean contains(Object o) { >>>>>>>>> if (o == null) { >>>>>>>>> // null values rejected by add >>>>>>>>> return false; >>>>>>>>> } >>>>>>>>> >>>>>>>>> ... >>>>>>>>> } >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> >>>>>>>>> Thanks in advance, >>>>>>>>> Tigran. > >>> <SubjectBenchmark.java>
# HG changeset patch # User Tigran Mkrtchyan <tigran.mkrtch...@desy.de> # Date 1587750415 -7200 # Fri Apr 24 19:46:55 2020 +0200 # Branch optimize-subject # Node ID 937a07d825c7f3e50d3c87d667c347835ce86f0b # Parent d18064736c65b4945f8ce43623b9a07bca0bd088 avoid throwing NPE in javax.security.auth.Subject.SecureSet#contains diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1202,8 +1202,13 @@ public final class Subject implements ja public boolean contains(Object o) { - Objects.requireNonNull(o, - ResourcesMgr.getString("invalid.null.input.s.")); + if (o == null) { + + // As SecureSet#add will reject all null values there is no need for a deep check. + // This short-cut makes collectionNullClean more effective when an instance of + // SecureSet is passed as the argument. + return false; + } final Iterator<E> e = iterator(); while (e.hasNext()) {