diff --git a/BinaryFormat/Chunks/PROP.cs b/BinaryFormat/Chunks/PROP.cs index 62f8185..9bbcde3 100644 --- a/BinaryFormat/Chunks/PROP.cs +++ b/BinaryFormat/Chunks/PROP.cs @@ -463,6 +463,13 @@ namespace RobloxFiles.BinaryFormat.Chunks readProperties(i => { int instId = instIds[i]; + + if (instId >= File.NumInstances) + { + RobloxFile.LogError($"Got out of bounds referent index in {ClassName}.{Name}!"); + return null; + } + return instId >= 0 ? File.Instances[instId] : null; }); @@ -1015,7 +1022,12 @@ namespace RobloxFiles.BinaryFormat.Chunks if (prop.Value != null) { Instance value = prop.CastValue(); - referent = int.Parse(value.Referent); + + if (value.IsDescendantOf(File)) + { + string refValue = value.Referent; + int.TryParse(refValue, out referent); + } } InstanceIds.Add(referent); diff --git a/RobloxFileFormat.dll b/RobloxFileFormat.dll index 3085fb1..cd020d1 100644 Binary files a/RobloxFileFormat.dll and b/RobloxFileFormat.dll differ diff --git a/Tokens/BinaryString.cs b/Tokens/BinaryString.cs index ec55759..33a94a2 100644 --- a/Tokens/BinaryString.cs +++ b/Tokens/BinaryString.cs @@ -22,6 +22,9 @@ namespace RobloxFiles.Tokens public void WriteProperty(Property prop, XmlDocument doc, XmlNode node) { + if (!prop.HasRawBuffer) + return; + byte[] data = prop.RawBuffer; string value = Convert.ToBase64String(data); diff --git a/Tree/Attributes.cs b/Tree/Attributes.cs index 42133dd..380c065 100644 --- a/Tree/Attributes.cs +++ b/Tree/Attributes.cs @@ -158,10 +158,8 @@ namespace RobloxFiles internal void WriteString(string value) { - int length = value.Length; - Writer.Write(length); - byte[] utf8 = Encoding.UTF8.GetBytes(value); + Writer.Write(utf8.Length); Writer.Write(utf8); } @@ -239,6 +237,10 @@ namespace RobloxFiles } } + public Attributes() : base() + { + } + internal Attributes(BinaryReader reader) { Initialize(reader); diff --git a/Tree/Instance.cs b/Tree/Instance.cs index 899d2d0..23bfa8d 100644 --- a/Tree/Instance.cs +++ b/Tree/Instance.cs @@ -64,7 +64,7 @@ namespace RobloxFiles public HashSet Tags { get; } = new HashSet(); /// The attributes defined for this Instance. - private Attributes AttributesImpl; + private Attributes AttributesImpl = new Attributes(); /// The public readonly access point of the attributes on this Instance. public IReadOnlyDictionary Attributes => AttributesImpl; @@ -161,7 +161,9 @@ namespace RobloxFiles if (key.Length > 100) return false; - if (!Attribute.SupportsType()) + Type type = value.GetType(); + + if (!Attribute.SupportsType(type)) return false; var attr = new Attribute(value); @@ -170,7 +172,6 @@ namespace RobloxFiles return true; } - /// Returns true if this Instance is an ancestor to the provided Instance. /// The instance whose descendance will be tested against this Instance. public bool IsAncestorOf(Instance descendant)