下面列出了java.io.ObjectStreamConstants#TC_NULL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public E readObject() throws ClassNotFoundException, IOException {
int b = peek();
if (b == ObjectStreamConstants.TC_NULL) {
return null;
} else {
E obj;
try {
obj = type.newInstance();
obj.readExternal(this);
return obj;
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
/*******************
* Handle a classDesc element.
*
* @param obj The RMIObject to populate with class names.
* @param dataStack The remaining data in the ReplyData packet.
******************/
private void handleClassDesc(RMIObject obj, LinkedList<Byte> dataStack) throws BaRMIeInvalidReplyDataPacketException {
String className;
//Delegate depending on the type of classDesc
switch(dataStack.pop()) {
//ClassDesc
case ObjectStreamConstants.TC_CLASSDESC:
//Read the class name
className = this.extractUtf8(dataStack);
//Skip over the serialVersionUID
this.extractLong(dataStack);
//Handle the classDescInfo element, pass the class name in as there may be annotations for the class in there
this.handleClassDescInfo(obj, dataStack, className);
break;
//ProxyClassDesc
case ObjectStreamConstants.TC_PROXYCLASSDESC:
//Handle the proxyClassDescInfo element
this.handleProxyClassDescInfo(obj, dataStack);
break;
//Null - e.g. when the super class is null
case ObjectStreamConstants.TC_NULL:
break;
//Unknown classDesc type
default:
throw new BaRMIeInvalidReplyDataPacketException("Unknown classDesc element type.");
}
}
/*******************
* Handle a classAnnotation element and return any string annotation
* elements in the classAnnotation.
*
* @param obj The RMIObject to populate with class names.
* @param dataStack The remaining data in the ReplyData packet.
* @return An ArrayList of strings representing any string annotations extracted from the stream.
******************/
private ArrayList<String> handleClassAnnotation(RMIObject obj, LinkedList<Byte> dataStack) throws BaRMIeInvalidReplyDataPacketException {
ArrayList<String> stringAnnotations;
byte b;
//Create the arraylist
stringAnnotations = new ArrayList<String>();
//Read elements from the stream until a TC_ENDBLOCKDATA element is read
while((b = dataStack.pop()) != ObjectStreamConstants.TC_ENDBLOCKDATA) {
//Handle the annotation
switch(b) {
//Read string annotations into an array list to return
case ObjectStreamConstants.TC_STRING:
stringAnnotations.add(this.extractUtf8(dataStack));
break;
//Skip over reference annotations
case ObjectStreamConstants.TC_REFERENCE:
//Read past the reference handle
this.extractInt(dataStack);
break;
//Ignore null annotations...
case ObjectStreamConstants.TC_NULL:
break;
//Unknown annotation type
default:
throw new BaRMIeInvalidReplyDataPacketException("Unknown classAnnotation element type (0x" + String.format("%02x", b) + ").");
}
}
//Return the string annotations
return stringAnnotations;
}
/*******************
* Handle an objectAnnotation element, extracting the object endpoint
* details if found.
*
* @param obj The RMIObject to populate with class names.
* @param dataStack The remaining data in the ReplyData packet.
******************/
private void handleObjectAnnotation(RMIObject obj, LinkedList<Byte> dataStack) throws BaRMIeInvalidReplyDataPacketException {
byte b;
//Read elements from the stream until a TC_ENDBLOCKDATA element is read
while((b = dataStack.pop()) != ObjectStreamConstants.TC_ENDBLOCKDATA) {
//Handle the annotation
switch(b) {
//Look for object endpoint details in block data elements
case ObjectStreamConstants.TC_BLOCKDATA:
//Push the block type back on to the stack and extract endpoint details if found
dataStack.push(ObjectStreamConstants.TC_BLOCKDATA);
this.extractObjectEndpointFromBlockData(obj, dataStack);
break;
//Skip over object annotations
case ObjectStreamConstants.TC_OBJECT:
this.handleNewObjectElement(obj, dataStack);
break;
//Ignore null annotations...
case ObjectStreamConstants.TC_NULL:
break;
//Unknown annotation type
default:
throw new BaRMIeInvalidReplyDataPacketException("Unknown classAnnotation element type (0x" + String.format("%02x", b) + ").");
}
}
}
public static byte[] generateObjectArrayPayload(int depth) throws Exception {
Object[] deepArray = createDeepArray(null, depth);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
new ObjectOutputStream(baos).writeObject(deepArray);
}
catch (Throwable e) {
// expected, there are not so many items inside
}
byte[] payload = baos.toByteArray();
/*
* Replace array length (1234) with MAX_ARRAY_SIZE to trigger allocating of as much memory as we can
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
new DataOutputStream(out).writeInt(OBJECT_ARRAY_SIZE_TEMP_VAL);
byte[] needle = out.toByteArray();
// find the needle in haystack
for (int i = 0; i < payload.length - 4; i++) {
if (payload[i+0] == needle[0] && payload[i+1] == needle[1] && payload[i+2] == needle[2] && payload[i+3] == needle[3]) {
out.reset();
new DataOutputStream(out).writeInt(MAX_ARRAY_SIZE);
// replace array length with max value
System.arraycopy(out.toByteArray(), 0, payload, i, 4);
i+= 4;
}
}
/*
* Truncate payload, we expect heap overflow before reaching end of stream
*/
int truncatedLength = payload.length;
for (int i = payload.length - 1; i > 0; i--) {
// there are only null values in the deepArray
if (payload[i] != ObjectStreamConstants.TC_NULL) {
truncatedLength = i + 1;
break;
}
}
byte[] truncated = new byte[truncatedLength];
System.arraycopy(payload, 0, truncated, 0, truncatedLength);
return truncated;
}