Skip to content

Commit 1533c0d

Browse files
[#70] Remove dead ProcessManagedReferenceData param; add explanatory comments
Drop the unused referencedTypeDataNode parameter (the referenced object's layout comes from its own TypeTree via GetRefTypeTypeTreeRoot, not from this node) and update both call sites. Add comments for the trickier mechanics: 4-byte alignment, the vector/map/staticvector array wrapper, Array node child layout, the StreamingInfo 32/64-bit offset field and its field-order difference from StreamedResource, PPtr<T> type-name parsing, and the >2GB size truncation/overflow assumptions in the stream and array handling.
1 parent 0b4ceb0 commit 1533c0d

2 files changed

Lines changed: 34 additions & 11 deletions

File tree

Analyzer/PPtrAndCrcProcessor.cs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,12 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
115115
}
116116
else if (node.Type == "vector" || node.Type == "map" || node.Type == "staticvector")
117117
{
118+
// These containers wrap an Array node as their single child; process that array.
118119
ProcessArray(node.Children[0], false, isInManagedReferenceRegistry);
119120
}
120121
else if (node.Type.StartsWith("PPtr<"))
121122
{
123+
// Extract T from the "PPtr<T>" type string.
122124
var startIndex = node.Type.IndexOf('<') + 1;
123125
var endIndex = node.Type.Length - 1;
124126
var referencedType = node.Type.Substring(startIndex, endIndex - startIndex);
@@ -127,12 +129,15 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
127129
}
128130
else if (node.Type == "StreamingInfo")
129131
{
132+
// StreamingInfo (Texture2D/Mesh) points at external stream data: offset, size, path.
130133
if (node.Children.Count != 3)
131134
throw new Exception("Invalid StreamingInfo");
132135

136+
// The offset field is 32- or 64-bit depending on the type tree version.
133137
var offset = node.Children[0].Size == 4 ? m_Reader.ReadInt32(m_Offset) : m_Reader.ReadInt64(m_Offset);
134138
m_Offset += node.Children[0].Size;
135139

140+
// size is an unsigned 32-bit field read as a signed int; streams >2GB are not handled.
136141
var size = m_Reader.ReadInt32(m_Offset);
137142
m_Offset += 4;
138143

@@ -148,6 +153,8 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
148153
}
149154
else if (node.Type == "StreamedResource")
150155
{
156+
// Like StreamingInfo but used by AudioClip/VideoClip; the fields are in a different
157+
// order - path first, then 64-bit offset and size.
151158
if (node.Children.Count != 3)
152159
throw new Exception("Invalid StreamedResource");
153160

@@ -159,6 +166,7 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
159166
var offset = m_Reader.ReadInt64(m_Offset);
160167
m_Offset += 8;
161168

169+
// 64-bit size truncated to int; streams >2GB are not handled.
162170
var size = (int)m_Reader.ReadInt64(m_Offset);
163171
m_Offset += 8;
164172

@@ -169,6 +177,7 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
169177
}
170178
else if (node.CSharpType == typeof(string))
171179
{
180+
// A string is serialized as a 4-byte length followed by its bytes; CRC the whole span.
172181
var prevOffset = m_Offset;
173182
m_Offset += m_Reader.ReadInt32(m_Offset) + 4;
174183
AppendCrc(prevOffset, (int)(m_Offset - prevOffset));
@@ -194,6 +203,8 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
194203
}
195204
}
196205

206+
// Unity pads certain fields to a 4-byte boundary. Re-align after the node if it, or any of
207+
// its children, is flagged to align.
197208
if (
198209
((int)node.MetaFlags & (int)TypeTreeMetaFlags.AlignBytes) != 0 ||
199210
((int)node.MetaFlags & (int)TypeTreeMetaFlags.AnyChildUsesAlignBytes) != 0
@@ -205,10 +216,13 @@ private void ProcessNode(TypeTreeNode node, bool isInManagedReferenceRegistry)
205216

206217
private void ProcessArray(TypeTreeNode node, bool isManagedReferenceRegistry, bool isInManagedReferenceRegistry)
207218
{
219+
// An Array node has two children: [0] is the int element count, [1] the element template.
208220
var dataNode = node.Children[1];
209221

210222
if (dataNode.IsBasicType)
211223
{
224+
// Fixed-size elements are stored contiguously, so CRC the 4-byte count plus all element
225+
// bytes in one range. (size * count can overflow int for very large arrays.)
212226
var arraySize = m_Reader.ReadInt32(m_Offset);
213227
AppendCrc(m_Offset, dataNode.Size * arraySize + 4);
214228
m_Offset += dataNode.Size * arraySize + 4;
@@ -235,16 +249,17 @@ private void ProcessArray(TypeTreeNode node, bool isManagedReferenceRegistry, bo
235249
else
236250
{
237251
// This is the version-2 "RefIds" array. Each element is a ReferencedObject
238-
// whose children are [rid, type, data]; read the rid here and hand the type
239-
// and data nodes to ProcessManagedReferenceData.
252+
// whose children are [rid, type, data]; read the rid here and pass the type
253+
// node to ProcessManagedReferenceData (the data node isn't needed - the layout
254+
// comes from the referenced type's own TypeTree).
240255
if (dataNode.Children.Count < 3)
241256
throw new Exception("Invalid ReferencedObject");
242257

243258
long rid = m_Reader.ReadInt64(m_Offset);
244259
AppendCrc(m_Offset, 8);
245260
m_Offset += 8;
246261

247-
ProcessManagedReferenceData(dataNode.Children[1], dataNode.Children[2], rid);
262+
ProcessManagedReferenceData(dataNode.Children[1], rid);
248263
}
249264
}
250265
}
@@ -303,16 +318,14 @@ private void ProcessManagedReferenceRegistry(TypeTreeNode node)
303318

304319
if (version == 1)
305320
{
306-
// Second child is the ReferencedObject.
321+
// Second child is the ReferencedObject; its first child describes the referenced type.
307322
var refObjNode = node.Children[1];
308-
// And its children are the referenced type and data nodes.
309323
var refTypeNode = refObjNode.Children[0];
310-
var refObjData = refObjNode.Children[1];
311324

312325
// Read entries until ProcessManagedReferenceData hits the sentinel; here the rid is
313326
// simply the entry's position.
314327
int i = 0;
315-
while (ProcessManagedReferenceData(refTypeNode, refObjData, i++))
328+
while (ProcessManagedReferenceData(refTypeNode, i++))
316329
{
317330
}
318331
}
@@ -342,10 +355,11 @@ private void ProcessManagedReferenceRegistry(TypeTreeNode node)
342355

343356
// Reads one registry entry: the concrete type's fully-qualified name (class, namespace,
344357
// assembly) followed by the object's data. The data is laid out according to that type's own
345-
// TypeTree, so we fetch it and recurse into it. Returns false at the end of a version-1
346-
// registry - marked either by the "Terminus" sentinel type or by a null/unknown rid (-1 / -2)
347-
// - and true otherwise.
348-
bool ProcessManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedTypeDataNode, long rid)
358+
// TypeTree, which we look up by name and recurse into - so the data node from the registry's
359+
// own TypeTree is not needed here; refTypeNode is used only to sanity-check the entry's shape.
360+
// Returns false at the end of a version-1 registry - marked either by the "Terminus" sentinel
361+
// type or by a null/unknown rid (-1 / -2) - and true otherwise.
362+
bool ProcessManagedReferenceData(TypeTreeNode refTypeNode, long rid)
349363
{
350364
if (refTypeNode.Children.Count < 3)
351365
throw new Exception("Invalid ReferencedManagedType");

bash.exe.stackdump

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Stack trace:
2+
Frame Function Args
3+
000FFFFC200 00210062B0E (00210297178, 00210275E3E, 00000000000, 000FFFFB100)
4+
000FFFFC200 0021004846A (00000000000, 00000000000, 00000000000, 00000000000)
5+
000FFFFC200 002100484A2 (00210297229, 000FFFFC0B8, 00000000000, 00000000000)
6+
000FFFFC200 002100D2FFE (00000000000, 00000000000, 00000000000, 00000000000)
7+
000FFFFC200 002100D3125 (000FFFFC210, 00000000000, 00000000000, 00000000000)
8+
001004F84B7 002100D46E5 (000FFFFC210, 00000000000, 00000000000, 00000000000)
9+
End of stack trace

0 commit comments

Comments
 (0)