8345073: Remove SecurityManager checks from sun.awt.image classes

Reviewed-by: azvegint, honkar
This commit is contained in:
Phil Race 2024-11-27 17:32:54 +00:00
parent 1e3a0fdb5d
commit 9527586923
8 changed files with 19 additions and 185 deletions

View File

@ -43,13 +43,6 @@ public class ByteArrayImageSource extends InputStreamImageSource {
imagelength = length;
}
final boolean checkSecurity(Object context, boolean quiet) {
// No need to check security. Applets and downloaded code can
// only make byte array image once they already have a handle
// on the image data anyway...
return true;
}
protected ImageDecoder getDecoder() {
InputStream is = new ByteArrayInputStream(imagedata, imageoffset,
imagelength);

View File

@ -34,20 +34,9 @@ public class FileImageSource extends InputStreamImageSource {
String imagefile;
public FileImageSource(String filename) {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(filename);
}
imagefile = filename;
}
final boolean checkSecurity(Object context, boolean quiet) {
// File based images only ever need to be checked statically
// when the image is retrieved from the cache.
return true;
}
protected ImageDecoder getDecoder() {
if (imagefile == null) {
return null;

View File

@ -33,8 +33,6 @@ class ImageConsumerQueue {
ImageConsumer consumer;
boolean interested;
Object securityContext;
boolean secure;
static ImageConsumerQueue removeConsumer(ImageConsumerQueue cqbase,
ImageConsumer ic,
@ -68,28 +66,18 @@ class ImageConsumerQueue {
ImageConsumerQueue(InputStreamImageSource src, ImageConsumer ic) {
consumer = ic;
interested = true;
// ImageReps do their own security at access time.
// Leaving this code throwing SecurityException for compatibility
if (ic instanceof ImageRepresentation) {
ImageRepresentation ir = (ImageRepresentation) ic;
if (ir.image.source != src) {
throw new SecurityException("ImageRep added to wrong image source");
}
secure = true;
} else {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
securityContext = security.getSecurityContext();
} else {
securityContext = null;
}
}
}
public String toString() {
return ("[" + consumer +
", " + (interested ? "" : "not ") + "interested" +
(securityContext != null ? ", " + securityContext : "") +
"]");
}
}

View File

@ -283,29 +283,23 @@ class ImageFetcher extends Thread {
final AppContext appContext = AppContext.getAppContext();
ThreadGroup threadGroup = appContext.getThreadGroup();
ThreadGroup fetcherThreadGroup;
try {
if (threadGroup.getParent() != null) {
// threadGroup is not the root, so we proceed
fetcherThreadGroup = threadGroup;
} else {
// threadGroup is the root ("system") ThreadGroup.
// We instead want to use its child: the "main"
// ThreadGroup. Thus, we start with the current
// ThreadGroup, and go up the tree until
// threadGroup.getParent().getParent() == null.
threadGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parent = threadGroup.getParent();
while ((parent != null)
&& (parent.getParent() != null)) {
threadGroup = parent;
parent = threadGroup.getParent();
}
fetcherThreadGroup = threadGroup;
}
} catch (SecurityException e) {
// Not allowed access to parent ThreadGroup -- just use
// the AppContext's ThreadGroup
fetcherThreadGroup = appContext.getThreadGroup();
if (threadGroup.getParent() != null) {
// threadGroup is not the root, so we proceed
fetcherThreadGroup = threadGroup;
} else {
// threadGroup is the root ("system") ThreadGroup.
// We instead want to use its child: the "main"
// ThreadGroup. Thus, we start with the current
// ThreadGroup, and go up the tree until
// threadGroup.getParent().getParent() == null.
threadGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parent = threadGroup.getParent();
while ((parent != null)
&& (parent.getParent() != null)) {
threadGroup = parent;
parent = threadGroup.getParent();
}
fetcherThreadGroup = threadGroup;
}
final ThreadGroup fetcherGroup = fetcherThreadGroup;

View File

@ -101,9 +101,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
/* REMIND: Only used for Frame.setIcon - should use ImageWatcher instead */
public synchronized void reconstruct(int flags) {
if (src != null) {
src.checkSecurity(null, false);
}
int missinginfo = flags & ~availinfo;
if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) {
numWaiters++;
@ -128,9 +125,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
}
public void setDimensions(int w, int h) {
if (src != null) {
src.checkSecurity(null, false);
}
image.setDimensions(w, h);
@ -190,17 +184,11 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
}
public void setProperties(Hashtable<?,?> props) {
if (src != null) {
src.checkSecurity(null, false);
}
image.setProperties(props);
newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0);
}
public void setColorModel(ColorModel model) {
if (src != null) {
src.checkSecurity(null, false);
}
srcModel = model;
// Check to see if model is INT_RGB
@ -323,9 +311,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
}
public void setHints(int h) {
if (src != null) {
src.checkSecurity(null, false);
}
hints = h;
}
@ -345,10 +330,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int poff;
int[] newLUT=null;
if (src != null) {
src.checkSecurity(null, false);
}
// REMIND: What if the model doesn't fit in default color model?
synchronized (this) {
if (bimage == null) {
@ -542,10 +523,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int lineOff=off;
int poff;
if (src != null) {
src.checkSecurity(null, false);
}
// REMIND: What if the model doesn't fit in default color model?
synchronized (this) {
if (bimage == null) {
@ -677,9 +654,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
private boolean consuming = false;
public void imageComplete(int status) {
if (src != null) {
src.checkSecurity(null, false);
}
boolean done;
int info;
switch (status) {
@ -749,9 +723,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
}
public boolean prepare(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -770,10 +741,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
}
public int check(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) {
addWatcher(iw);
}
@ -785,9 +752,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int x, int y, Color bg,
ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -816,9 +780,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int x, int y, int w, int h,
Color bg, ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -849,9 +810,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int sx1, int sy1, int sx2, int sy2,
Color bg, ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -885,9 +843,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
{
Graphics2D g2 = (Graphics2D) g;
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,

View File

@ -40,8 +40,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
boolean awaitingFetch = false;
abstract boolean checkSecurity(Object context, boolean quiet);
int countConsumers(ImageConsumerQueue cq) {
int i = 0;
while (cq != null) {
@ -83,7 +81,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
}
synchronized void addConsumer(ImageConsumer ic, boolean produce) {
checkSecurity(null, false);
for (ImageDecoder id = decoders; id != null; id = id.next) {
if (id.isConsumer(ic)) {
// This consumer is already being fed.
@ -99,25 +96,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
cq.next = consumers;
consumers = cq;
} else {
if (!cq.secure) {
Object context = null;
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
context = security.getSecurityContext();
}
if (cq.securityContext == null) {
cq.securityContext = context;
} else if (!cq.securityContext.equals(context)) {
// If there are two different security contexts that both
// have a handle on the same ImageConsumer, then there has
// been a security breach and whether or not they trade
// image data is small fish compared to what they could be
// trading. Throw a Security exception anyway...
errorConsumer(cq, false);
throw new SecurityException("Applets are trading image data!");
}
}
cq.interested = true;
}
if (produce && decoder == null) {
@ -303,13 +281,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
awaitingFetch = false;
}
while (cq != null) {
if (cq.interested) {
// Now that there is a decoder, security may have changed
// so reverify it here, just in case.
if (!checkSecurity(cq.securityContext, true)) {
errorConsumer(cq, false);
}
}
cq = cq.next;
}
}

View File

@ -71,9 +71,6 @@ public class ToolkitImage extends Image {
}
public ImageProducer getSource() {
if (src != null) {
src.checkSecurity(null, false);
}
return source;
}
@ -88,9 +85,6 @@ public class ToolkitImage extends Image {
* If the width isn't known, then the image is reconstructed.
*/
public int getWidth() {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.WIDTH) == 0) {
reconstruct(ImageObserver.WIDTH);
}
@ -103,9 +97,6 @@ public class ToolkitImage extends Image {
* notified when the data is available.
*/
public synchronized int getWidth(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.WIDTH) == 0) {
addWatcher(iw, true);
if ((availinfo & ImageObserver.WIDTH) == 0) {
@ -120,9 +111,6 @@ public class ToolkitImage extends Image {
* If the height isn't known, then the image is reconstructed.
*/
public int getHeight() {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.HEIGHT) == 0) {
reconstruct(ImageObserver.HEIGHT);
}
@ -135,9 +123,6 @@ public class ToolkitImage extends Image {
* notified when the data is available.
*/
public synchronized int getHeight(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.HEIGHT) == 0) {
addWatcher(iw, true);
if ((availinfo & ImageObserver.HEIGHT) == 0) {
@ -162,9 +147,6 @@ public class ToolkitImage extends Image {
throw new NullPointerException("null property name is not allowed");
}
if (src != null) {
src.checkSecurity(null, false);
}
if (properties == null) {
addWatcher(observer, true);
if (properties == null) {
@ -179,16 +161,10 @@ public class ToolkitImage extends Image {
}
public boolean hasError() {
if (src != null) {
src.checkSecurity(null, false);
}
return (availinfo & ImageObserver.ERROR) != 0;
}
public int check(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) == 0 &&
((~availinfo) & (ImageObserver.WIDTH |
ImageObserver.HEIGHT |
@ -199,9 +175,6 @@ public class ToolkitImage extends Image {
}
public void preload(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ALLBITS) == 0) {
addWatcher(iw, true);
}
@ -273,9 +246,6 @@ public class ToolkitImage extends Image {
}
public void flush() {
if (src != null) {
src.checkSecurity(null, false);
}
ImageRepresentation ir;
synchronized (this) {
@ -297,9 +267,6 @@ public class ToolkitImage extends Image {
}
public synchronized ImageRepresentation getImageRep() {
if (src != null) {
src.checkSecurity(null, false);
}
if (imagerep == null) {
imagerep = makeImageRep();
}

View File

@ -55,30 +55,6 @@ public class URLImageSource extends InputStreamImageSource {
this(uc.getURL(), uc);
}
final boolean checkSecurity(Object context, boolean quiet) {
// If actualHost is not null, then the host/port parameters that
// the image was actually fetched from were different than the
// host/port parameters the original URL specified for at least
// one of the download attempts. The original URL security was
// checked when the applet got a handle to the image, so we only
// need to check for the real host/port.
if (actualHost != null) {
try {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkConnect(actualHost, actualPort, context);
}
} catch (SecurityException e) {
if (!quiet) {
throw e;
}
return false;
}
}
return true;
}
private synchronized URLConnection getConnection() throws IOException {
URLConnection c;
if (conn != null) {
@ -106,6 +82,7 @@ public class URLImageSource extends InputStreamImageSource {
// listed in the original URL, or it can come from one other
// host/port that the URL is redirected to. More than that
// and we give up and just throw a SecurityException.
// This is not directly related to SecurityManager so keep it.
if (actualHost != null && (!actualHost.equals(u.getHost()) ||
actualPort != u.getPort()))
{