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) <noreply@anthropic.com>
This commit is contained in:
dchukkapalli-dev
2026-07-13 19:59:06 +00:00
parent 413c38dbcb
commit 7d28eb7d52
+8 -2
View File
@@ -231,8 +231,14 @@ namespace AsarSharp.PickleTools
private void Resize(int newCapacity) private void Resize(int newCapacity)
{ {
newCapacity = AlignInt(newCapacity, PAYLOAD_UNIT); newCapacity = AlignInt(newCapacity, PAYLOAD_UNIT);
byte[] newHeader = new byte[_header.Length + newCapacity]; // The backing array must hold the header plus the full advertised
Buffer.BlockCopy(_header, 0, newHeader, 0, _header.Length); // 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; _header = newHeader;
_capacityAfterHeader = newCapacity; _capacityAfterHeader = newCapacity;
} }