From 7d28eb7d5234ee37fe1a7f719a5a2a7eaaf5b0d5 Mon Sep 17 00:00:00 2001 From: dchukkapalli-dev <12871391+dchukkapalli-dev@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:59:06 +0000 Subject: [PATCH] fix(asar): correct Pickle payload buffer allocation Pickle.Resize allocated the backing array as _header.Length + newCapacity but advertised _capacityAfterHeader = newCapacity. On the first growth _header is still empty, so the array ended up _headerSize (4) bytes short of the header + capacity it claimed. A write that fills the payload then overran the buffer, throwing an ArgumentException when the serialised asar header was 4089-4092 bytes. Allocate _headerSize + newCapacity instead, matching Chromium's realloc(header_size_ + new_capacity). Co-Authored-By: Claude Opus 4.8 (1M context) --- AsarSharp/PickleTools/Pickle.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/AsarSharp/PickleTools/Pickle.cs b/AsarSharp/PickleTools/Pickle.cs index 169d15d..c192a8f 100644 --- a/AsarSharp/PickleTools/Pickle.cs +++ b/AsarSharp/PickleTools/Pickle.cs @@ -231,8 +231,14 @@ namespace AsarSharp.PickleTools private void Resize(int newCapacity) { newCapacity = AlignInt(newCapacity, PAYLOAD_UNIT); - byte[] newHeader = new byte[_header.Length + newCapacity]; - Buffer.BlockCopy(_header, 0, newHeader, 0, _header.Length); + // The backing array must hold the header plus the full advertised + // payload capacity (matches Chromium's realloc(header_size_ + new_capacity)). + // Sizing it from _header.Length under-allocates by _headerSize on the + // first growth (when _header is still empty), leaving the payload region + // _headerSize bytes short of _capacityAfterHeader and overrunning the + // buffer when a write fills the payload. + byte[] newHeader = new byte[_headerSize + newCapacity]; + Buffer.BlockCopy(_header, 0, newHeader, 0, Math.Min(_header.Length, newHeader.Length)); _header = newHeader; _capacityAfterHeader = newCapacity; }