diff options
author | Thomas Meyer <[email protected]> | 2012-04-10 19:10:43 +0200 |
---|---|---|
committer | Thomas Meyer <[email protected]> | 2012-04-10 19:10:43 +0200 |
commit | b942de5bc239dded7694330f6f7c9d25e4352b03 (patch) | |
tree | dd578a6894b9534b4ad283b9e0381cb5206eaa94 /netx/net/sourceforge | |
parent | 055577a36255b0ae4dc130793c12f5207c11bd2c (diff) |
Validate the recently_used file at every load. This will fix the StringIndex-
OutOfBoundsException for a corrupted path entry thrown in
CacheUtil.pathToURLPath(). This Exception was catched in
RessourceTracker.Downloader.run() and only printed in debug mode.
Diffstat (limited to 'netx/net/sourceforge')
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java | 67 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/CacheUtil.java | 143 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/resources/Messages.properties | 9 |
3 files changed, 115 insertions, 104 deletions
diff --git a/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java b/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java index e148bd3..a1eef67 100644 --- a/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java +++ b/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java @@ -36,6 +36,7 @@ exception statement from your version. */ package net.sourceforge.jnlp.cache; +import java.util.Set; import static net.sourceforge.jnlp.runtime.Translator.R; import java.io.File; @@ -45,6 +46,7 @@ import java.nio.channels.OverlappingFileLockException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Map.Entry; @@ -107,6 +109,57 @@ enum CacheLRUWrapper { */ public synchronized void load() { cacheOrder.load(); + /* + * clean up possibly corrupted entries + */ + if (checkData()) { + if (JNLPRuntime.isDebug()) { + new LruCacheException().printStackTrace(); + } + System.out.println(R("CFakeCache")); + store(); + System.out.println(R("CFakedCache")); + } + } + + /** + * check content of cacheOrder and remove invalid/corrupt entries + * + * @return true, if cache was coruupted and affected entry removed + */ + private boolean checkData () { + boolean modified = false; + Set<Entry<Object, Object>> q = cacheOrder.entrySet(); + for (Iterator<Entry<Object, Object>> it = q.iterator(); it.hasNext();) { + Entry<Object, Object> currentEntry = it.next(); + + final String key = (String) currentEntry.getKey(); + final String path = (String) currentEntry.getValue(); + + // 1. check key format: "milliseconds,number" + try { + String sa[] = key.split(","); + Long l1 = Long.parseLong(sa[0]); + Long l2 = Long.parseLong(sa[1]); + } catch (Exception ex) { + it.remove(); + modified = true; + continue; + } + + // 2. check path format - does the path look correct? + if (path != null) { + if (path.indexOf(cacheDir) < 0) { + it.remove(); + modified = true; + } + } else { + it.remove(); + modified = true; + } + } + + return modified; } /** @@ -174,15 +227,11 @@ enum CacheLRUWrapper { Collections.sort(entries, new Comparator<Entry<String, String>>() { @Override public int compare(Entry<String, String> e1, Entry<String, String> e2) { - try { - Long t1 = Long.parseLong(e1.getKey().split(",")[0]); - Long t2 = Long.parseLong(e2.getKey().split(",")[0]); - - int c = t1.compareTo(t2); - return c < 0 ? 1 : (c > 0 ? -1 : 0); - } catch (Exception e) { - throw new LruCacheException(R("Corrupt LRU file entries")); - } + Long t1 = Long.parseLong(e1.getKey().split(",")[0]); + Long t2 = Long.parseLong(e2.getKey().split(",")[0]); + + int c = t1.compareTo(t2); + return c < 0 ? 1 : (c > 0 ? -1 : 0); } }); return entries; diff --git a/netx/net/sourceforge/jnlp/cache/CacheUtil.java b/netx/net/sourceforge/jnlp/cache/CacheUtil.java index 320b0f2..2e9aaaa 100644 --- a/netx/net/sourceforge/jnlp/cache/CacheUtil.java +++ b/netx/net/sourceforge/jnlp/cache/CacheUtil.java @@ -307,8 +307,8 @@ public class CacheUtil { cacheFile = getCacheFileIfExist(urlToPath(source, "")); if (cacheFile == null) { // We did not find a copy of it. cacheFile = makeNewCacheFile(source, version); - } - lruHandler.store(); + } else + lruHandler.store(); lruHandler.unlock(); } return cacheFile; @@ -323,48 +323,16 @@ public class CacheUtil { private static File getCacheFileIfExist(File urlPath) { synchronized (lruHandler) { File cacheFile = null; - int tries = 0; - List<Entry<String, String>> entries = null; - do { - try { - tries++; - entries = lruHandler.getLRUSortedEntries(); - } catch (LruCacheException ex) { - if (tries == 1) { - ex.printStackTrace(); - System.out.println(R("CFakeCache")); - lruHandler.clearLRUSortedEntries(); - lruHandler.store(); - System.out.println(R("CFakedCache")); - } else if (tries == 2) { - ex.printStackTrace(); - System.out.println(R("CStillCorupted")); - boolean clearingresult = CacheUtil.clearCache(); - if (!clearingresult) { - throw new InternalError(R("CCleaningUnsuccessful")); - } - System.out.println(R("CClearedReloading")); - lruHandler.clearLRUSortedEntries(); - lruHandler.store(); - System.out.println(R("CReloadRestarting")); - - } else { - throw new InternalError(R("CStillBroken")); - } - - } - } while (entries == null); + List<Entry<String, String>> entries = lruHandler.getLRUSortedEntries(); // Start searching from the most recent to least recent. for (Entry<String, String> e : entries) { final String key = e.getKey(); final String path = e.getValue(); - if (path != null) { - if (pathToURLPath(path).equals(urlPath.getPath())) { // Match found. - cacheFile = new File(path); - lruHandler.updateEntry(key); - break; // Stop searching since we got newest one already. - } + if (pathToURLPath(path).equals(urlPath.getPath())) { // Match found. + cacheFile = new File(path); + lruHandler.updateEntry(key); + break; // Stop searching since we got newest one already. } } return cacheFile; @@ -561,6 +529,7 @@ public class CacheUtil { * This will remove all old cache items. */ public static void cleanCache() { + if (okToClearCache()) { // First we want to figure out which stuff we need to delete. HashSet<String> keep = new HashSet<String>(); @@ -579,57 +548,55 @@ public class CacheUtil { for (Entry<String, String> e : lruHandler.getLRUSortedEntries()) { // Check if the item is contained in cacheOrder. final String key = e.getKey(); - final String value = e.getValue(); - - if (value != null) { - File file = new File(value); - PropertiesFile pf = new PropertiesFile(new File(value + ".info")); - boolean delete = Boolean.parseBoolean(pf.getProperty("delete")); - - /* - * This will get me the root directory specific to this cache item. - * Example: - * cacheDir = /home/user1/.icedtea/cache - * file.getPath() = /home/user1/.icedtea/cache/0/http/www.example.com/subdir/a.jar - * rStr first becomes: /0/http/www.example.com/subdir/a.jar - * then rstr becomes: /home/user1/.icedtea/cache/0 - */ - String rStr = file.getPath().substring(cacheDir.length()); - rStr = cacheDir + rStr.substring(0, rStr.indexOf(File.separatorChar, 1)); - long len = file.length(); - - if (keep.contains(file.getPath().substring(rStr.length()))) { - lruHandler.removeEntry(key); - continue; - } - - /* - * we remove entries from our lru if any of the following condition is met. - * Conditions: - * - delete: file has been marked for deletion. - * - !file.isFile(): if someone tampered with the directory, file doesn't exist. - * - maxSize >= 0 && curSize + len > maxSize: If a limit was set and the new size - * on disk would exceed the maximum size. - */ - if (delete || !file.isFile() || (maxSize >= 0 && curSize + len > maxSize)) { - lruHandler.removeEntry(key); - remove.add(rStr); - } else { - curSize += len; - keep.add(file.getPath().substring(rStr.length())); - - for (File f : file.getParentFile().listFiles()) { - if (!(f.equals(file) || f.equals(pf.getStoreFile()))){ - try { - FileUtils.recursiveDelete(f, f); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + final String path = e.getValue(); + + File file = new File(path); + PropertiesFile pf = new PropertiesFile(new File(path + ".info")); + boolean delete = Boolean.parseBoolean(pf.getProperty("delete")); + + /* + * This will get me the root directory specific to this cache item. + * Example: + * cacheDir = /home/user1/.icedtea/cache + * file.getPath() = /home/user1/.icedtea/cache/0/http/www.example.com/subdir/a.jar + * rStr first becomes: /0/http/www.example.com/subdir/a.jar + * then rstr becomes: /home/user1/.icedtea/cache/0 + */ + String rStr = file.getPath().substring(cacheDir.length()); + rStr = cacheDir + rStr.substring(0, rStr.indexOf(File.separatorChar, 1)); + long len = file.length(); + + if (keep.contains(file.getPath().substring(rStr.length()))) { + lruHandler.removeEntry(key); + continue; + } + + /* + * we remove entries from our lru if any of the following condition is met. + * Conditions: + * - delete: file has been marked for deletion. + * - !file.isFile(): if someone tampered with the directory, file doesn't exist. + * - maxSize >= 0 && curSize + len > maxSize: If a limit was set and the new size + * on disk would exceed the maximum size. + */ + if (delete || !file.isFile() || (maxSize >= 0 && curSize + len > maxSize)) { + lruHandler.removeEntry(key); + remove.add(rStr); + continue; + } + + curSize += len; + keep.add(file.getPath().substring(rStr.length())); + + for (File f : file.getParentFile().listFiles()) { + if (!(f.equals(file) || f.equals(pf.getStoreFile()))) { + try { + FileUtils.recursiveDelete(f, f); + } catch (IOException e1) { + e1.printStackTrace(); } } - } else { - lruHandler.removeEntry(key); + } } lruHandler.store(); diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties index a0801b6..9866fe7 100644 --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -192,13 +192,8 @@ CChooseCache=Choose a cache directory... CChooseCacheInfo=Netx needs a location for storing cache files.
CChooseCacheDir=Cache directory
CCannotClearCache=Can not clear cache at this time
-CFakeCache=Cache is corrupt. Disabling.
-CFakedCache=Cache is corrupt and has been disabled. It is strongly recommended that you run 'javaws -Xclearcache' and rerun your application as soon as possible.
-CStillCorupted=Cache is still corrupt, clearing it.
-CCleaningUnsuccessful=Unable to clear cache due to running javaws instance. Please try to shut down all instances of javaws, run 'javaws -Xclearcache', and rerun your jnlp file
-CClearedReloading=Cache cleared, re-loading.
-CReloadRestarting=Cache re-loaded and application re-starting. It is strongly recommended that you run 'javaws -Xclearcache' and re-run your application as soon as possible.
-CStillBroken=Unable to fix corrupt cache. Please shutdown all javaws instances, run 'javaws -Xclearcache', and re-start your application.
+CFakeCache=Cache is corrupt. Fixing.
+CFakedCache=Cache is corrupt and has been fixed. It is strongly recommended that you run 'javaws -Xclearcache' and rerun your application as soon as possible.
# Security
SFileReadAccess=The application has requested read access to {0}. Do you want to allow this action?
|