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; 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() { protected ImageDecoder getDecoder() {
InputStream is = new ByteArrayInputStream(imagedata, imageoffset, InputStream is = new ByteArrayInputStream(imagedata, imageoffset,
imagelength); imagelength);

View File

@ -34,20 +34,9 @@ public class FileImageSource extends InputStreamImageSource {
String imagefile; String imagefile;
public FileImageSource(String filename) { public FileImageSource(String filename) {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(filename);
}
imagefile = 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() { protected ImageDecoder getDecoder() {
if (imagefile == null) { if (imagefile == null) {
return null; return null;

View File

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

View File

@ -283,29 +283,23 @@ class ImageFetcher extends Thread {
final AppContext appContext = AppContext.getAppContext(); final AppContext appContext = AppContext.getAppContext();
ThreadGroup threadGroup = appContext.getThreadGroup(); ThreadGroup threadGroup = appContext.getThreadGroup();
ThreadGroup fetcherThreadGroup; ThreadGroup fetcherThreadGroup;
try { if (threadGroup.getParent() != null) {
if (threadGroup.getParent() != null) { // threadGroup is not the root, so we proceed
// threadGroup is not the root, so we proceed fetcherThreadGroup = threadGroup;
fetcherThreadGroup = threadGroup; } else {
} else { // threadGroup is the root ("system") ThreadGroup.
// threadGroup is the root ("system") ThreadGroup. // We instead want to use its child: the "main"
// We instead want to use its child: the "main" // ThreadGroup. Thus, we start with the current
// ThreadGroup. Thus, we start with the current // ThreadGroup, and go up the tree until
// ThreadGroup, and go up the tree until // threadGroup.getParent().getParent() == null.
// threadGroup.getParent().getParent() == null. threadGroup = Thread.currentThread().getThreadGroup();
threadGroup = Thread.currentThread().getThreadGroup(); ThreadGroup parent = threadGroup.getParent();
ThreadGroup parent = threadGroup.getParent(); while ((parent != null)
while ((parent != null) && (parent.getParent() != null)) {
&& (parent.getParent() != null)) { threadGroup = parent;
threadGroup = parent; parent = threadGroup.getParent();
parent = threadGroup.getParent(); }
} fetcherThreadGroup = threadGroup;
fetcherThreadGroup = threadGroup;
}
} catch (SecurityException e) {
// Not allowed access to parent ThreadGroup -- just use
// the AppContext's ThreadGroup
fetcherThreadGroup = appContext.getThreadGroup();
} }
final ThreadGroup fetcherGroup = fetcherThreadGroup; 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 */ /* REMIND: Only used for Frame.setIcon - should use ImageWatcher instead */
public synchronized void reconstruct(int flags) { public synchronized void reconstruct(int flags) {
if (src != null) {
src.checkSecurity(null, false);
}
int missinginfo = flags & ~availinfo; int missinginfo = flags & ~availinfo;
if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) { if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) {
numWaiters++; numWaiters++;
@ -128,9 +125,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
} }
public void setDimensions(int w, int h) { public void setDimensions(int w, int h) {
if (src != null) {
src.checkSecurity(null, false);
}
image.setDimensions(w, h); image.setDimensions(w, h);
@ -190,17 +184,11 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
} }
public void setProperties(Hashtable<?,?> props) { public void setProperties(Hashtable<?,?> props) {
if (src != null) {
src.checkSecurity(null, false);
}
image.setProperties(props); image.setProperties(props);
newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0); newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0);
} }
public void setColorModel(ColorModel model) { public void setColorModel(ColorModel model) {
if (src != null) {
src.checkSecurity(null, false);
}
srcModel = model; srcModel = model;
// Check to see if model is INT_RGB // Check to see if model is INT_RGB
@ -323,9 +311,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
} }
public void setHints(int h) { public void setHints(int h) {
if (src != null) {
src.checkSecurity(null, false);
}
hints = h; hints = h;
} }
@ -345,10 +330,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int poff; int poff;
int[] newLUT=null; int[] newLUT=null;
if (src != null) {
src.checkSecurity(null, false);
}
// REMIND: What if the model doesn't fit in default color model? // REMIND: What if the model doesn't fit in default color model?
synchronized (this) { synchronized (this) {
if (bimage == null) { if (bimage == null) {
@ -542,10 +523,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int lineOff=off; int lineOff=off;
int poff; int poff;
if (src != null) {
src.checkSecurity(null, false);
}
// REMIND: What if the model doesn't fit in default color model? // REMIND: What if the model doesn't fit in default color model?
synchronized (this) { synchronized (this) {
if (bimage == null) { if (bimage == null) {
@ -677,9 +654,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
private boolean consuming = false; private boolean consuming = false;
public void imageComplete(int status) { public void imageComplete(int status) {
if (src != null) {
src.checkSecurity(null, false);
}
boolean done; boolean done;
int info; int info;
switch (status) { switch (status) {
@ -749,9 +723,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
} }
public boolean prepare(ImageObserver iw) { public boolean prepare(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) { if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) { if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -770,10 +741,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
} }
public int check(ImageObserver iw) { public int check(ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) { if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) {
addWatcher(iw); addWatcher(iw);
} }
@ -785,9 +752,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
int x, int y, Color bg, int x, int y, Color bg,
ImageObserver iw) { ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) { if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) { if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, 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, int x, int y, int w, int h,
Color bg, ImageObserver iw) { Color bg, ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) { if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) { if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, 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, int sx1, int sy1, int sx2, int sy2,
Color bg, ImageObserver iw) { Color bg, ImageObserver iw) {
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) { if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) { if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
@ -885,9 +843,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
{ {
Graphics2D g2 = (Graphics2D) g; Graphics2D g2 = (Graphics2D) g;
if (src != null) {
src.checkSecurity(null, false);
}
if ((availinfo & ImageObserver.ERROR) != 0) { if ((availinfo & ImageObserver.ERROR) != 0) {
if (iw != null) { if (iw != null) {
iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,

View File

@ -40,8 +40,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
boolean awaitingFetch = false; boolean awaitingFetch = false;
abstract boolean checkSecurity(Object context, boolean quiet);
int countConsumers(ImageConsumerQueue cq) { int countConsumers(ImageConsumerQueue cq) {
int i = 0; int i = 0;
while (cq != null) { while (cq != null) {
@ -83,7 +81,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
} }
synchronized void addConsumer(ImageConsumer ic, boolean produce) { synchronized void addConsumer(ImageConsumer ic, boolean produce) {
checkSecurity(null, false);
for (ImageDecoder id = decoders; id != null; id = id.next) { for (ImageDecoder id = decoders; id != null; id = id.next) {
if (id.isConsumer(ic)) { if (id.isConsumer(ic)) {
// This consumer is already being fed. // This consumer is already being fed.
@ -99,25 +96,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
cq.next = consumers; cq.next = consumers;
consumers = cq; consumers = cq;
} else { } 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; cq.interested = true;
} }
if (produce && decoder == null) { if (produce && decoder == null) {
@ -303,13 +281,6 @@ public abstract class InputStreamImageSource implements ImageProducer,
awaitingFetch = false; awaitingFetch = false;
} }
while (cq != null) { 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; cq = cq.next;
} }
} }

View File

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

View File

@ -55,30 +55,6 @@ public class URLImageSource extends InputStreamImageSource {
this(uc.getURL(), uc); 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 { private synchronized URLConnection getConnection() throws IOException {
URLConnection c; URLConnection c;
if (conn != null) { if (conn != null) {
@ -106,6 +82,7 @@ public class URLImageSource extends InputStreamImageSource {
// listed in the original URL, or it can come from one other // listed in the original URL, or it can come from one other
// host/port that the URL is redirected to. More than that // host/port that the URL is redirected to. More than that
// and we give up and just throw a SecurityException. // 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()) || if (actualHost != null && (!actualHost.equals(u.getHost()) ||
actualPort != u.getPort())) actualPort != u.getPort()))
{ {