Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two.
diff --git a/Lib/plistlib.py b/Lib/plistlib.py
index dcb0f9c..8c148a8 100644
--- a/Lib/plistlib.py
+++ b/Lib/plistlib.py
@@ -619,10 +619,7 @@
                 offset_table_offset
             ) = struct.unpack('>6xBBQQQ', trailer)
             self._fp.seek(offset_table_offset)
-            offset_format = '>' + _BINARY_FORMAT[offset_size] * num_objects
-            self._ref_format = _BINARY_FORMAT[self._ref_size]
-            self._object_offsets = struct.unpack(
-                offset_format, self._fp.read(offset_size * num_objects))
+            self._object_offsets = self._read_ints(num_objects, offset_size)
             return self._read_object(self._object_offsets[top_object])
 
         except (OSError, IndexError, struct.error):
@@ -638,9 +635,16 @@
 
         return tokenL
 
+    def _read_ints(self, n, size):
+        data = self._fp.read(size * n)
+        if size in _BINARY_FORMAT:
+            return struct.unpack('>' + _BINARY_FORMAT[size] * n, data)
+        else:
+            return tuple(int.from_bytes(data[i: i + size], 'big')
+                         for i in range(0, size * n, size))
+
     def _read_refs(self, n):
-        return struct.unpack(
-            '>' + self._ref_format * n, self._fp.read(n * self._ref_size))
+        return self._read_ints(n, self._ref_size)
 
     def _read_object(self, offset):
         """