[Red5commits] [1794] fixed object reference bugs in AMF3 decoder (Jira APPSERVER-95)

jbauch luke at codegent.com
Wed Mar 28 15:50:07 EST 2007


fixed object reference bugs in AMF3 decoder (Jira APPSERVER-95)


Timestamp: 03/28/07 15:50:07 EST (less than one hour ago) 
Change: 1794 
Author: jbauch

Files (see diff or trac for details): 
doc/trunk/changelog.txt
java/server/trunk/src/org/red5/io/amf3/Input.java
java/server/trunk/src/org/red5/io/object/BaseInput.java


Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1794

Index: /java/server/trunk/src/org/red5/io/amf3/Input.java
===================================================================
--- /java/server/trunk/src/org/red5/io/amf3/Input.java (revision 1698)
+++ /java/server/trunk/src/org/red5/io/amf3/Input.java (revision 1794)
@@ -62,4 +62,11 @@
 	}
 	
+	/**
+	 * Dummy class that is stored as reference for objects currently
+	 * being deserialized that reference themselves. 
+	 */
+	protected class PendingObject {
+	}
+	
     /**
      * Logger
@@ -326,4 +333,6 @@
 		amf3_mode += 1;
 		Map<String, Object> properties = null;
+		PendingObject pending = new PendingObject();
+		int tempRefId = storeReference(pending);
 		switch (type & 0x03) {
 		case AMF3.TYPE_OBJECT_PROPERTY:
@@ -379,5 +388,12 @@
 			if ("".equals(className)) {
 				// "anonymous" object, load as Map
-				storeReference(properties);
+				// Resolve circular references
+				for (Map.Entry<String, Object> entry: properties.entrySet()) {
+					if (entry.getValue() == pending) {
+						entry.setValue(properties);
+					}
+				}
+				
+				storeReference(tempRefId, properties);
 				result = properties;
 			} else if ("RecordSet".equals(className)) {
@@ -391,7 +407,12 @@
 				result = newInstance(className);
 				if (result != null) {
-					storeReference(properties);
+					storeReference(tempRefId, result);
 					Class resultClass = result.getClass();
 					for (Map.Entry<String, Object> entry: properties.entrySet()) {
+						// Resolve circular references
+						if (entry.getValue() == pending) {
+							entry.setValue(result);
+						}
+						
 						try {
 							try {
Index: /java/server/trunk/src/org/red5/io/object/BaseInput.java
===================================================================
--- /java/server/trunk/src/org/red5/io/object/BaseInput.java (revision 1698)
+++ /java/server/trunk/src/org/red5/io/object/BaseInput.java (revision 1794)
@@ -34,5 +34,5 @@
      * References map
      */
-	protected Map refMap = new HashMap();
+	protected Map<Integer, Object> refMap = new HashMap<Integer, Object>();
 
     /**
@@ -45,8 +45,21 @@
 	 * @param obj  Object to store
 	 */
-	protected void storeReference(Object obj) {
-		refMap.put(Integer.valueOf(refId++), obj);
+	protected int storeReference(Object obj) {
+		int newRefId = refId++;
+		refMap.put(Integer.valueOf(newRefId), obj);
+		return newRefId;
 	}
 
+	/**
+	 * Replace a referenced object with another one. This is used
+	 * by the AMF3 deserializer to handle circular references.
+	 * 
+	 * @param refId
+	 * @param newRef
+	 */
+	protected void storeReference(int refId, Object newRef) {
+		refMap.put(Integer.valueOf(refId), newRef);
+	}
+	
 	/**
 	 * Clears the map
Index: /doc/trunk/changelog.txt
===================================================================
--- /doc/trunk/changelog.txt (revision 1791)
+++ /doc/trunk/changelog.txt (revision 1794)
@@ -42,4 +42,5 @@
 - fixed NoSuchElementException when iterating connections during disconnect
   (Jira APPSERVER-94)
+- reference bugs im AMF3 decoder fixed (Jira APPSERVER-95)
 
 


Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.



More information about the Red5commits mailing list