PriorityQueue(collection) should throw NPE

David Holmes David.Holmes at oracle.com
Fri May 7 02:37:35 UTC 2010


Hi Martin,

CR 6950540 filed. (Chris might want to tidy it up :) )

Changes look okay to me.

Thanks,
David

Martin Buchholz said the following on 05/07/10 12:19:
> David,
> 
> Of course you're right.
> I didn't realize that the hole was one-element nulls.
> 
> (Why is software always 10 times harder than you'd think?)
> 
> Updated webrev, with lots more tests for corner cases.
> 
> I still need a bug filed in bugtraq.
> 
> Martin
> 
> On Thu, May 6, 2010 at 16:53, David Holmes <David.Holmes at oracle.com> wrote:
>> Hi Martin,
>>
>> Martin Buchholz said the following on 05/07/10 09:13:
>>> On Thu, May 6, 2010 at 15:58, David Holmes <David.Holmes at oracle.com>
>>> wrote:
>>>>> Fix:
>>>>>
>>>>>
>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/
>>>> I'm not sure this is necessarily the right fix. It seems to me that
>>>> incidental nulls will be caught in many/most cases by the sorting code
>>>> for
>>>> collections assumed to contain Comparable's.
>>> The comparator might accept nulls.
>> True but a Comparator is only used if the Collection is a SortedSet or a
>> PriorityQueue. For any other Collection the elements must implement
>> Comparable and the code in:
>>
>>   private void siftDownComparable(int k, E x) {
>>        Comparable<? super E> key = (Comparable<? super E>)x;
>>        int half = size >>> 1;        // loop while a non-leaf
>>        while (k < half) {
>>            int child = (k << 1) + 1; // assume left child is least
>>            Object c = queue[child];
>>            int right = child + 1;
>>            if (right < size &&
>>                ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
>>                c = queue[child = right];
>>            if (key.compareTo((E) c) <= 0)
>>                break;
>>            queue[k] = c;
>>            k = child;
>>        }
>>        queue[k] = key;
>>    }
>>
>> will throw NPE at key.compareTo if the item is null. (There's probably a
>> missed case where the collection contains only a null element).
>>
>>> But even if it doesn't, it is possible to create a "corrupted" PQ
>>> using the PQ(collection) constructor, and we don't allow
>>> that sort of thing in java.util.
>> But that's the hole we're fixing now.
>>
>>>> And we don't need to check when
>>>> filling from an existing PriorityQueue.
>>> Strictly speaking, the source PriorityQueue might be a subclass that
>>> has been modified to accept nulls.
>> Yes I suppose. So we could change from an instanceof test to a getClass()
>> test.
>>
>>> But yes, we could have a version of the fix that only checks for nulls
>>> if the source is not a PQ.
>>>
>>>> So is it only the case for filling
>>>> from a SortedSet that needs the explicit null check?
>>> The source can be an arbitrary Collection.
>> But as noted above for anything other than a SortedSet (or corrupt PQ) the
>> sorting code will already catch nulls.
>>
>> Cheers,
>> David
>>
>>> Martin
>>>
>>>> David
>>>>



More information about the core-libs-dev mailing list