Christoph Schindler avatar Christoph Schindler committed acbbddb

Properly handle references in nested data structures.

Comments (0)

Files changed (2)

         # trailer info (object count == len(offset_table)
         self.offset_size = 1
         self.ref_size = 1
-        self.top_level_object = 0
+        self.top_level_object_ref = 0
         self.offset_table_offset = 0
 
     def dump(self, obj):
         file-like object).
         """
         self.write(self.enc_header())
-        self.write(self.enc_object_table(obj))
+        ref, object = self.enc_object_table(obj)
+        self.top_level_object_ref = ref
+        self.write(object)
         self.write(self.enc_offset_table())
         self.write(self.enc_trailer())
 
         t = type(obj)
         f = self.dispatch.get(t)
 
-        # put object at the current position and move back the offset table
+        ref = len(self.offset_table)
         self.offset_table.append(self.offset_table_offset)
 
         if f:
-            return f(self, obj)     # unbound method
+            return ref, f(self, obj)     # unbound method
 
         raise TypeError("Don't know how to encode %s object" % t)
 
 
     def enc_trailer(self):
         trailer = struct.pack('!xxxxxxBBQQQ', self.offset_size, self.ref_size,
-                              len(self.offset_table), self.top_level_object,
+                              len(self.offset_table), self.top_level_object_ref,
                               self.offset_table_offset)
         return trailer
 
         self.offset_table_offset += count
 
         for element in obj:
-            objects.append(self.enc_object_table(element))
-            object_ref = struct.pack('>B', len(self.offset_table)-1)
+            ref, object = self.enc_object_table(element)
+            objects.append(object)
+            object_ref = struct.pack('>B', ref)
             object_refs.append(object_ref)
 
         return wrapper + ''.join(object_refs) + ''.join(objects)
         self.offset_table_offset += 2*count
 
         for key in obj.keys():
-            keys.append(self.enc_object_table(str(key)))
-            key_ref = struct.pack('>B', len(self.offset_table)-1)
+            ref, object = self.enc_object_table(str(key))
+            keys.append(object)
+            key_ref = struct.pack('>B', ref)
             key_refs.append(key_ref)
 
         for value in obj.values():
-            objects.append(self.enc_object_table(value))
-            object_ref = struct.pack('>B', len(self.offset_table)-1)
+            ref, object = self.enc_object_table(value)
+            objects.append(object)
+            object_ref = struct.pack('>B', ref)
             object_refs.append(object_ref)
 
         return (wrapper + ''.join(key_refs) + ''.join(object_refs) +

plist/tests/test_encode_lists_binary.py

     (range(14), 'bplist00\xae\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x10\x00\x10\x01\x10\x02\x10\x03\x10\x04\x10\x05\x10\x06\x10\x07\x10\x08\x10\t\x10\n\x10\x0b\x10\x0c\x10\r\x08\x17\x19\x1b\x1d\x1f!#%\')+-/1\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003'),
     (range(15), 'bplist00\xaf\x10\x0f\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x00\x10\x01\x10\x02\x10\x03\x10\x04\x10\x05\x10\x06\x10\x07\x10\x08\x10\t\x10\n\x10\x0b\x10\x0c\x10\r\x10\x0e\x08\x1a\x1c\x1e "$&(*,.0246\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008'),
     (range(16), 'bplist00\xaf\x10\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x10\x00\x10\x01\x10\x02\x10\x03\x10\x04\x10\x05\x10\x06\x10\x07\x10\x08\x10\t\x10\n\x10\x0b\x10\x0c\x10\r\x10\x0e\x10\x0f\x08\x1b\x1d\x1f!#%\')+-/13579\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;'),
+    ([[0, 1, 2], [3, 4, 5]], 'bplist00\xa2\x01\x05\xa3\x02\x03\x04\x10\x00\x10\x01\x10\x02\xa3\x06\x07\x08\x10\x03\x10\x04\x10\x05\x08\x0b\x0f\x11\x13\x15\x19\x1b\x1d\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f'),
 ]
 
 def test_encode_lists_binary():
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.