Commit b6961182 authored by hpi1's avatar hpi1

Use dummy SecurityManager to grab all Xlet file access

Cache all accessed files on demand when VFS root is not accessible with Java I/O.
parent 7fc6531e
libudfread @ f73b9e1e
Subproject commit 3f1bc248626598a9f05f6f0131a0e37f8817edc5
Subproject commit f73b9e1ebbf940814cc118c2e9f258e372088595
......@@ -60,6 +60,13 @@ public class BDJLoader {
return null;
}
public static void accessFile(String file) {
VFSCache localCache = vfsCache;
if (localCache != null) {
localCache.accessFile(file);
}
}
public static String getCachedFile(String path) {
VFSCache localCache = vfsCache;
if (localCache != null) {
......
/*
* This file is part of libbluray
* Copyright (C) 2015 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.videolan;
import java.io.FilePermission;
import java.security.Permission;
/*
* Dummy security manager to grab all file access
*/
class BDJSecurityManager extends SecurityManager {
public void checkPermission(Permission perm) {
/*
try {
java.security.AccessController.checkPermission(perm);
} catch (java.security.AccessControlException ex) {
System.err.println(" *** caught " + ex + " at " + Logger.dumpStack());
throw ex;
}
*/
}
public void checkRead(String file) {
//super.checkRead(file);
BDJLoader.accessFile(file);
}
}
......@@ -49,10 +49,20 @@ public class Libbluray {
protected static void init(long nativePointer, String discID, String discRoot,
String persistentRoot, String budaRoot) {
System.setProperty("bluray.vfs.root", discRoot);
System.setProperty("dvb.persistent.root", persistentRoot);
System.setProperty("bluray.bindingunit.root", budaRoot);
if (discRoot == null) {
try {
System.setSecurityManager(new BDJSecurityManager());
} catch (Exception ex) {
System.err.println("System.setSecurityManager() failed: " + ex);
System.err.println("BD-J file access won't work");
}
} else {
System.setProperty("bluray.vfs.root", discRoot);
}
Libbluray.nativePointer = nativePointer;
DiscManager.getDiscManager().setCurrentDisc(discID);
......@@ -141,6 +151,13 @@ public class Libbluray {
stopTitle(true);
BDJLoader.shutdown();
BDJActionManager.shutdown();
try {
System.setSecurityManager(null);
} catch (Exception ex) {
System.err.println("System.setSecurityManager(null) failed: " + ex);
}
MountManager.unmountAll();
GUIManager.shutdown();
BDToolkit.shutdownDisc();
......
......@@ -54,6 +54,14 @@ class VFSCache {
cacheRoot = CacheDir.create("VFSCache").getPath() + File.separator;
fontRoot = CacheDir.create("Font").getPath() + File.separator;
vfsRoot = System.getProperty("bluray.vfs.root");
if (vfsRoot == null) {
System.err.println("disc root is in UDF");
System.setProperty("bluray.vfs.root", cacheRoot);
vfsRoot = cacheRoot;
cacheAll = true;
}
if (!vfsRoot.endsWith(File.separator)) {
vfsRoot = vfsRoot + File.separator;
}
......@@ -238,6 +246,71 @@ class VFSCache {
return tmpFile;
}
/*
* Accessing any file triggers security manager checks.
* -> we cache the file (on demand) so that it will be accessible by standard Java I/O.
*/
boolean inAccessFile = false;
protected void accessFile(String absPath) {
if (!cacheAll) {
/* BD-ROM filesystem is accessible with standard I/O */
return;
}
if (!absPath.startsWith(vfsRoot)) {
/* path does not map to VFS */
return;
}
accessFileSynced(absPath);
}
protected synchronized void accessFileSynced(String absPath) {
if (inAccessFile) {
/* avoid recursion from SecurityManager checks */
return;
}
inAccessFile = true;
accessFileImp(absPath);
inAccessFile = false;
}
private void accessFileImp(String absPath) {
if (BDFileSystem.nativeFileExists(absPath)) {
/* file is already cached */
return;
}
String relPath = absPath.substring(vfsRootLength);
String[] names = org.videolan.Libbluray.listBdFiles(relPath, true);
if (names == null) {
/* this is regular file */
} else {
/* this is directory, make sure it exists */
new File(absPath).mkdirs();
return;
}
/* do not cache .m2ts streams */
if (relPath.startsWith("BDMV" + File.separator + "STREAM" + File.separator)) {
return;
}
/* create the directory */
int sepPos = relPath.lastIndexOf(File.separatorChar);
if (sepPos > 0) {
String absDir = cacheRoot + relPath.substring(0, sepPos);
new File(absDir).mkdirs();
}
/* finally, copy the file to cache */
Libbluray.cacheBdRomFile(relPath, cacheRoot + relPath);
}
/*
* Add file from binding unit data area to cache
*/
......@@ -257,6 +330,10 @@ class VFSCache {
*/
public synchronized String map(String absPath) {
if (cacheAll) {
return absPath;
}
if (!absPath.startsWith(vfsRoot)) {
//logger.info(absPath + " not in BDMV/JAR");
return absPath;
......@@ -276,6 +353,7 @@ class VFSCache {
private String vfsRoot = null;
private String fontRoot = null;
private int vfsRootLength = 0;
private boolean cacheAll = false;
private static final String jarDir = "BDMV" + File.separator + "JAR" + File.separator;
private static final String fontDir = "BDMV" + File.separator + "AUXDATA" + File.separator;
......
......@@ -382,7 +382,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_videolan_Libbluray_listBdFilesN(JNIEnv *
dp = disc_open_dir(disc, path);
}
if (!dp) {
BD_DEBUG(DBG_JNI | DBG_CRIT, "failed opening directory %s\n", path);
BD_DEBUG(DBG_JNI, "failed opening directory %s\n", path);
(*env)->ReleaseStringUTFChars(env, jpath, path);
return NULL;
}
......
......@@ -1206,10 +1206,6 @@ static int _start_bdj(BLURAY *bd, unsigned title)
#ifdef USING_BDJAVA
if (bd->bdjava == NULL) {
const char *root = disc_root(bd->disc);
if (!root) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Title %d: BD-J with disc images is not supported yet\n", title);
return 0;
}
bd->bdjava = bdj_open(root, bd, bd->disc_info.bdj_disc_id, &bd->bdjstorage);
if (!bd->bdjava) {
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment