From cf29ea560a75ec347bc8f5d08ce2db23e17d7c15 Mon Sep 17 00:00:00 2001 From: asterlore <3082227873@qq.com> Date: Tue, 4 Aug 2026 23:49:35 +0800 Subject: [PATCH] Fix ASAR parsing failure with unpacked entries --- ArcFormats/ArcASAR.cs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/ArcFormats/ArcASAR.cs b/ArcFormats/ArcASAR.cs index 9d677de1e..0ee3e591f 100644 --- a/ArcFormats/ArcASAR.cs +++ b/ArcFormats/ArcASAR.cs @@ -41,6 +41,12 @@ class AsarNode [JsonProperty("offset")] public string Offset { get; set; } + + [JsonProperty("unpacked")] + public bool Unpacked { get; set; } + + [JsonProperty("link")] + public string Link { get; set; } } [Export(typeof(ArchiveFormat))] @@ -59,17 +65,34 @@ public AsarOpener () public override ArcFile TryOpen (ArcView file) { + if (file.MaxOffset < 0x10) + return null; if (file.View.ReadUInt32 (4) != file.View.ReadUInt32 (8) + 4) return null; uint index_size = file.View.ReadUInt32 (0x0C); + if (index_size > file.MaxOffset - 0x10) + return null; string json = file.View.ReadString (0x10, index_size, Encoding.UTF8); - var dict = JsonConvert.DeserializeObject (json); + AsarNode dict; + try + { + dict = JsonConvert.DeserializeObject (json); + } + catch (JsonException) + { + return null; + } + if (null == dict) + return null; var dir = new List (); - ParseIndex (dir, dict, (uint)((index_size + 0x10 + 3) & ~3)); + long pad = (0x10L + index_size + 3) & ~3L; + ParseIndex (dir, dict, pad); + dir.RemoveAll (e => e.Size != 0 && !e.CheckPlacement (file.MaxOffset)); return new ArcFile (file, this, dir); } - internal void ParseIndex (List dir, AsarNode dict, uint pad, string cur = "") { + void ParseIndex (List dir, AsarNode dict, long pad, string cur = "") + { if (dict.Files != null) { foreach (var kv in dict.Files) @@ -81,10 +104,15 @@ internal void ParseIndex (List dir, AsarNode dict, uint pad, string cur = } else { + if (dict.Unpacked || !string.IsNullOrEmpty (dict.Link) || string.IsNullOrEmpty (dict.Offset)) + return; + long offset; + if (!long.TryParse (dict.Offset, out offset)) + return; var entry = new Entry { Name = cur, Size = dict.Size, - Offset = uint.Parse (dict.Offset) + pad, + Offset = offset + pad, Type = FormatCatalog.Instance.GetTypeFromName (cur) }; dir.Add (entry);