src/share/classes/javax/security/auth/Subject.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -192,21 +192,23 @@
* @param privCredentials the {@code Set} of private credentials
* to be associated with this {@code Subject}.
*
* @exception NullPointerException if the specified
* {@code principals}, {@code pubCredentials},
- * or {@code privCredentials} are {@code null}.
+ * or {@code privCredentials} are {@code null},
+ * or a null value exists within any of these three
+ * Sets.
*/
public Subject(boolean readOnly, Set<? extends Principal> principals,
Set<?> pubCredentials, Set<?> privCredentials)
{
-
- if (principals == null ||
- pubCredentials == null ||
- privCredentials == null)
+ if (collectionNullClean(principals) == false ||
+ collectionNullClean(pubCredentials) == false ||
+ collectionNullClean(privCredentials) == false) {
throw new NullPointerException
(ResourcesMgr.getString("invalid.null.input.s."));
+ }
this.principals = Collections.synchronizedSet(new SecureSet<Principal>
(this, PRINCIPAL_SET, principals));
this.pubCredentials = Collections.synchronizedSet(new SecureSet<Object>
(this, PUB_CREDENTIAL_SET, pubCredentials));
@@ -968,14 +970,10 @@
readOnly = gf.get("readOnly", false);
Set<Principal> inputPrincs = (Set<Principal>)gf.get("principals", null);
// Rewrap the principals into a SecureSet
- if (inputPrincs == null) {
- throw new NullPointerException
- (ResourcesMgr.getString("invalid.null.input.s."));
- }
try {
principals = Collections.synchronizedSet(new SecureSet<Principal>
(this, PRINCIPAL_SET, inputPrincs));
} catch (NullPointerException npe) {
// Sometimes people deserialize the principals set only.
@@ -991,10 +989,34 @@
this.privCredentials = Collections.synchronizedSet
(new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
}
/**
+ * Tests for null-clean collections (both non-null reference and
+ * no null elements)
+ *
+ * @param coll A {@code Collection} to be tested for null references
+ *
+ * @return true if {@code coll} is non-null and contains no null
+ * elements, false otherwise.
+ */
+ private static boolean collectionNullClean(Collection<?> coll) {
+ boolean isClean = false;
+
+ try {
+ isClean = (coll != null) && !coll.contains(null);
+ } catch (NullPointerException npe) {
+ // A null-hostile collection may choose to return null if
+ // contains(null) is called on it rather than returning false.
+ // If so then we know no nulls are present.
+ isClean = true;
+ }
+
+ return isClean;
+ }
+
+ /**
* Prevent modifications unless caller has permission.
*
* @serial include
*/
private static class SecureSet<E>
@@ -1096,10 +1118,15 @@
};
}
public boolean add(E o) {
+ if (o == null) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
if (subject.isReadOnly()) {
throw new IllegalStateException
(ResourcesMgr.getString("Subject.is.read.only"));
}
@@ -1137,10 +1164,15 @@
return false;
}
public boolean remove(Object o) {
+ if (o == null) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
final Iterator<E> e = iterator();
while (e.hasNext()) {
E next;
if (which != Subject.PRIV_CREDENTIAL_SET) {
next = e.next();
@@ -1151,24 +1183,25 @@
return e.next();
}
});
}
- if (next == null) {
- if (o == null) {
- e.remove();
- return true;
- }
- } else if (next.equals(o)) {
+ if (next.equals(o)) {
e.remove();
return true;
}
}
return false;
}
public boolean contains(Object o) {
+
+ if (o == null) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
final Iterator<E> e = iterator();
while (e.hasNext()) {
E next;
if (which != Subject.PRIV_CREDENTIAL_SET) {
next = e.next();
@@ -1192,23 +1225,32 @@
return e.next();
}
});
}
- if (next == null) {
- if (o == null) {
- return true;
- }
- } else if (next.equals(o)) {
+ if (next.equals(o)) {
return true;
}
}
return false;
}
+ public boolean addAll(Collection<? extends E> c) {
+ if (collectionNullClean(c) == false) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
+ return (super.addAll(c));
+ }
+
public boolean removeAll(Collection<?> c) {
- Objects.requireNonNull(c);
+ if (collectionNullClean(c) == false) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
boolean modified = false;
final Iterator<E> e = iterator();
while (e.hasNext()) {
E next;
if (which != Subject.PRIV_CREDENTIAL_SET) {
@@ -1222,34 +1264,38 @@
});
}
Iterator<?> ce = c.iterator();
while (ce.hasNext()) {
- Object o = ce.next();
- if (next == null) {
- if (o == null) {
- e.remove();
- modified = true;
- break;
- }
- } else if (next.equals(o)) {
+ if (next.equals(ce.next())) {
e.remove();
modified = true;
break;
}
}
}
return modified;
}
+ public boolean containsAll(Collection<?> c) {
+ if (collectionNullClean(c) == false) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
+ return super.containsAll(c);
+ }
+
public boolean retainAll(Collection<?> c) {
- Objects.requireNonNull(c);
+ if (collectionNullClean(c) == false) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
boolean modified = false;
- boolean retain = false;
final Iterator<E> e = iterator();
while (e.hasNext()) {
- retain = false;
E next;
if (which != Subject.PRIV_CREDENTIAL_SET) {
next = e.next();
} else {
next = java.security.AccessController.doPrivileged
@@ -1258,30 +1304,16 @@
return e.next();
}
});
}
- Iterator<?> ce = c.iterator();
- while (ce.hasNext()) {
- Object o = ce.next();
- if (next == null) {
- if (o == null) {
- retain = true;
- break;
- }
- } else if (next.equals(o)) {
- retain = true;
- break;
- }
- }
-
- if (!retain) {
+ if (c.contains(next) == false) {
e.remove();
- retain = false;
modified = true;
}
}
+
return modified;
}
public void clear() {
final Iterator<E> e = iterator();
@@ -1336,16 +1368,23 @@
ObjectInputStream.GetField fields = ois.readFields();
subject = (Subject) fields.get("this$0", null);
which = fields.get("which", 0);
LinkedList<E> tmp = (LinkedList<E>) fields.get("elements", null);
+
+ if (Subject.collectionNullClean(tmp) == false) {
+ throw new NullPointerException
+ (ResourcesMgr.getString("invalid.null.input.s."));
+ }
+
if (tmp.getClass() != LinkedList.class) {
elements = new LinkedList<E>(tmp);
} else {
elements = tmp;
}
}
+
}
/**
* This class implements a {@code Set} which returns only
* members that are an instance of a specified Class.