6631533: ICC_Profile allows detecting if some files exist
authorbae
Thu, 10 Sep 2009 14:15:47 +0400
changeset 4206 8925b5c1334b
parent 4205 89ffcfc5fc26
child 4207 a9ca0ff33862
6631533: ICC_Profile allows detecting if some files exist Reviewed-by: prr, hawtin
jdk/src/share/classes/java/awt/color/ICC_Profile.java
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java	Thu Sep 10 14:04:38 2009 +0400
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java	Thu Sep 10 14:15:47 2009 +0400
@@ -863,7 +863,9 @@
         case ColorSpace.CS_PYCC:
             synchronized(ICC_Profile.class) {
                 if (PYCCprofile == null) {
-                    if (getProfileFile("PYCC.pf") != null) {
+                    if (!sun.jkernel.DownloadManager.isJREComplete() ||
+                        standardProfileExists("PYCC.pf"))
+                    {
                         ProfileDeferralInfo pInfo =
                             new ProfileDeferralInfo("PYCC.pf",
                                                     ColorSpace.TYPE_3CLR, 3,
@@ -961,15 +963,15 @@
      * and it does not permit read access to the given file.
      */
     public static ICC_Profile getInstance(String fileName) throws IOException {
-    ICC_Profile thisProfile;
-    FileInputStream fis;
+        ICC_Profile thisProfile;
+        FileInputStream fis = null;
+
 
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            security.checkRead(fileName);
+        File f = getProfileFile(fileName);
+        if (f != null) {
+            fis = new FileInputStream(f);
         }
-
-        if ((fis = openProfile(fileName)) == null) {
+        if (fis == null) {
             throw new IOException("Cannot open file " + fileName);
         }
 
@@ -1081,11 +1083,22 @@
     void activateDeferredProfile() throws ProfileDataException {
         byte profileData[];
         FileInputStream fis;
-        String fileName = deferralInfo.filename;
+        final String fileName = deferralInfo.filename;
 
         profileActivator = null;
         deferralInfo = null;
-        if ((fis = openProfile(fileName)) == null) {
+        PrivilegedAction<FileInputStream> pa = new PrivilegedAction<FileInputStream>() {
+            public FileInputStream run() {
+                File f = getStandardProfileFile(fileName);
+                if (f != null) {
+                    try {
+                        return new FileInputStream(f);
+                    } catch (FileNotFoundException e) {}
+                }
+                return null;
+            }
+        };
+        if ((fis = AccessController.doPrivileged(pa)) == null) {
             throw new ProfileDataException("Cannot open file " + fileName);
         }
         try {
@@ -1784,86 +1797,107 @@
      * available, such as a profile for sRGB.  Built-in profiles use .pf as
      * the file name extension for profiles, e.g. sRGB.pf.
      */
-    private static FileInputStream openProfile(final String fileName) {
-        return (FileInputStream)java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
-                File f = privilegedGetProfileFile(fileName);
-                if (f != null) {
-                    try {
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {
-                    }
-                }
-                return null;
-            }
-        });
-    }
-
-    private static File getProfileFile(final String fileName) {
-        return (File)java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
-                return privilegedGetProfileFile(fileName);
-            }
-        });
-    }
-
-    /*
-     * this version is called from doPrivileged in openProfile
-     * or getProfileFile, so the whole method is privileged!
-     */
-
-    private static File privilegedGetProfileFile(String fileName) {
+    private static File getProfileFile(String fileName) {
         String path, dir, fullPath;
 
         File f = new File(fileName); /* try absolute file name */
-
+        if (f.isAbsolute()) {
+            /* Rest of code has little sense for an absolute pathname,
+               so return here. */
+            return f.isFile() ? f : null;
+        }
         if ((!f.isFile()) &&
                 ((path = System.getProperty("java.iccprofile.path")) != null)){
                                     /* try relative to java.iccprofile.path */
                 StringTokenizer st =
                     new StringTokenizer(path, File.pathSeparator);
-                while (st.hasMoreTokens() && (!f.isFile())) {
+                while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) {
                     dir = st.nextToken();
                         fullPath = dir + File.separatorChar + fileName;
                     f = new File(fullPath);
+                    if (!isChildOf(f, dir)) {
+                        f = null;
+                    }
                 }
             }
 
-        if ((!f.isFile()) &&
+        if (((f == null) || (!f.isFile())) &&
                 ((path = System.getProperty("java.class.path")) != null)) {
                                     /* try relative to java.class.path */
                 StringTokenizer st =
                     new StringTokenizer(path, File.pathSeparator);
-                while (st.hasMoreTokens() && (!f.isFile())) {
+                while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) {
                     dir = st.nextToken();
                         fullPath = dir + File.separatorChar + fileName;
                     f = new File(fullPath);
+                    if (!isChildOf(f, dir)) {
+                        f = null;
+                    }
                 }
             }
-
-        if (!f.isFile()) { /* try the directory of built-in profiles */
-            dir = System.getProperty("java.home") +
-                File.separatorChar + "lib" + File.separatorChar + "cmm";
-            fullPath = dir + File.separatorChar + fileName;
-                f = new File(fullPath);
-                if (!f.isFile()) {
-                    //make sure file was installed in the kernel mode
-                    try {
-                        //kernel uses platform independent paths =>
-                        //   should not use platform separator char
-                        sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName);
-                    } catch (IOException ioe) {}
-                }
-            }
-
-        if (f.isFile()) {
+        if ((f == null) || (!f.isFile())) {
+            /* try the directory of built-in profiles */
+            f = getStandardProfileFile(fileName);
+        }
+        if (f != null && f.isFile()) {
             return f;
         }
         return null;
     }
 
+    /**
+     * Returns a file object corresponding to a built-in profile
+     * specified by fileName.
+     * If there is no built-in profile with such name, then the method
+     * returns null.
+     */
+    private static File getStandardProfileFile(String fileName) {
+        String dir = System.getProperty("java.home") +
+            File.separatorChar + "lib" + File.separatorChar + "cmm";
+        String fullPath = dir + File.separatorChar + fileName;
+        File f = new File(fullPath);
+        if (!f.isFile()) {
+            //make sure file was installed in the kernel mode
+            try {
+                //kernel uses platform independent paths =>
+                //   should not use platform separator char
+                sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName);
+            } catch (IOException ioe) {}
+        }
+        return (f.isFile() && isChildOf(f, dir)) ? f : null;
+    }
+
+    /**
+     * Checks whether given file resides inside give directory.
+     */
+    private static boolean isChildOf(File f, String dirName) {
+        try {
+            File dir = new File(dirName);
+            String canonicalDirName = dir.getCanonicalPath();
+            if (!canonicalDirName.endsWith(File.separator)) {
+                canonicalDirName += File.separator;
+            }
+            String canonicalFileName = f.getCanonicalPath();
+            return canonicalFileName.startsWith(canonicalDirName);
+        } catch (IOException e) {
+            /* we do not expect the IOException here, because invocation
+             * of this function is always preceeded by isFile() call.
+             */
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether built-in profile specified by fileName exists.
+     */
+    private static boolean standardProfileExists(final String fileName) {
+        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    return getStandardProfileFile(fileName) != null;
+                }
+            });
+    }
+
 
     /*
      * Serialization support.