package org.kde.kjas.server;
import java.lang.reflect.*;
import java.net.URLClassLoader;
import java.net.URL;
/**
* wrapper for the javaplugin.jar Broken11ClassFixer.
* Uses the reflection api to wrap the class sun.plugin.security.Broken11ClassFixer
* from the javaplugin.jar archive which can be found in the jre/lib directory.
*/
public class KJASBrokenClassFixer {
private static Class fixerClass = null;
private static Method _process;
private static Method _getProcessedData;
private static Method _getProcessedDataOffset;
private static Method _getProcessedDataLength;
private static boolean initialized = false;
private static final String fixerClassName = "sun.plugin.security.Broken11ClassFixer";
private Object fixer = null;
private byte [] bytes;
private int offset;
private int length;
/**
* creates a new KJASBrokenClassFixer.
* If it is the first one to be created, it tries to load the class
* sun.plugin.security.Broken11ClassFixer from the jar file
* lib/javaplugin.jar in the java jre directory.
*/
public KJASBrokenClassFixer() {
init();
if (fixerClass != null) {
try {
fixer = fixerClass.newInstance();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
/**
* loads the class sun.plugin.security.Broken11ClassFixer,
* initializes the methods, ...
*/
private synchronized void init() {
if (initialized) {
return;
}
try {
URL [] urls = { new URL(
"file", "", 0,
System.getProperty("java.home")
+ System.getProperty("file.separator")
+ "lib"
+ System.getProperty("file.separator")
+ "javaplugin.jar"), new URL(
"file", "", 0,
System.getProperty("java.home")
+ System.getProperty("file.separator")
+ "lib"
+ System.getProperty("file.separator")
+ "plugin.jar")
};
URLClassLoader loader = new URLClassLoader(urls);
fixerClass = Class.forName(fixerClassName, true, loader);
Main.debug("Loaded " + fixerClass);
final Class [] parameterTypes = {
(new byte[1]).getClass(),
Integer.TYPE,
Integer.TYPE
};
final Class [] noParameter = new Class[0];
_process = fixerClass.getMethod("process", parameterTypes);
_getProcessedData = fixerClass.getMethod("getProcessedData", noParameter);
_getProcessedDataOffset = fixerClass.getMethod("getProcessedDataOffset", noParameter);
_getProcessedDataLength = fixerClass.getMethod("getProcessedDataLength", noParameter);
} catch (Throwable e) {
e.printStackTrace();
} finally {
initialized = true;
}
}
/**
* scan the broken bytes and create new ones.
* If the wrapped class could not be loaded or
* no instance of Broken11ClassFixer could be instantiated,
* this is a noop and later calls to getProcessedData() etc.
* will return the original data passed as arguments in this
* call.
*/
public boolean process(byte [] b, int off, int len) {
if (fixer != null) {
try {
Object [] args = new Object[3];
args[0] = b;
args[1] = new Integer(off);
args[2] = new Integer(len);
Object [] none = new Object[0];
_process.invoke(fixer, args);
this.bytes = (byte[])_getProcessedData.invoke(fixer, none);
this.offset = ((Integer)_getProcessedDataOffset.invoke(fixer, none)).intValue();
this.length = ((Integer)_getProcessedDataLength.invoke(fixer, none)).intValue();
return true;
} catch (Throwable e) {
}
}
this.bytes = b;
this.offset = off;
this.length = len;
return false;
}
/**
* get the offset in the processed byte array
*/
public int getProcessedDataOffset() {
return offset;
}
/**
* get the length of the processed data
*/
public int getProcessedDataLength() {
return length;
}
/**
* get the processed (fixed) data
*/
public byte [] getProcessedData() {
return bytes;
}
}