Posted 4 July 2026, 10:40 am EST - Updated 4 July 2026, 10:44 am EST
(written entirely by AI)
Title: C1.Excel: C1XLBook.Load throws ArgumentException (“output char buffer is too small”) on valid .xls files with non-ASCII OLE storage names
Product / Version: C1.Excel 10.0.20261.269 (NuGet, netstandard2.0), .NET 10 console app, Windows 11
Description
C1XLBook.Load fails with an ArgumentException on a valid legacy .xls file (BIFF, OLE compound document) that Excel itself opens without problems:
System.ArgumentException: The output char buffer is too small to contain the decoded characters,
encoding codepage '65001' and fallback 'System.Text.DecoderReplacementFallback'. (Parameter 'chars')
at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder, Boolean nothingDecoded)
...
at System.IO.BinaryReader.ReadChar()
at di.b..ctor(di a, Byte[] b, Int32 c)
at di.m_g()
at di.m_f(Stream a)
at di.m_e(String a)
at di..ctor(String a)
at C1.Excel.C1XLBook.m_aa(String a, Boolean b)
at C1.Excel.C1XLBook.Load(String fileName, FileFormat format, Boolean fillSheets)
at C1.Excel.C1XLBook.Load(String fileName)
Repro code
using (var book = new C1XLBook())
book.Load(@"...\foo.xls"); // throws
Root cause
The OLE compound-file directory parser (internal class di.b, constructor b(di, byte[], int)) reads the
128-byte directory entries. Per the CFB spec, the entry name at offset 0 is UTF-16LE. The code however reads
it with a BinaryReader created without an encoding argument, so it defaults to UTF-8:
using BinaryReader binaryReader = new BinaryReader(memoryStream); // defaults to UTF-8!
...
for (int num2 = 0; num2 < num - 1; num2 += 2)
{
memoryStream.Position = num2;
char c2 = binaryReader.ReadChar(); // decodes UTF-16LE bytes as UTF-8
...
}
This works by coincidence as long as every character in the name is ASCII (“Workbook”,
“\x05SummaryInformation”, …). But my file contains an MsoDataStore sub-storage whose entry name
contains non-ASCII UTF-16 characters, raw name bytes:
33 00 C0 00 45 00 35 00 49 00 43 00 4E 00 DF 00 4F 00 D4 00 43 00 DD 00 ...
When ReadChar() hits the 0xC0 byte, the UTF-8 decoder treats it as an invalid lead byte; combined with
the following 0x00 it emits two chars in one call (U+FFFD replacement + U+0000) into ReadChar()'s
single-char buffer, which throws the ArgumentException above (a documented BinaryReader.ReadChar
behavior for the default UTF-8 encoding).
Such names are common: Office writes MsoDataStore storages with base64-style names containing high
characters, so any .xls that ever had custom XML parts attached can trigger this. The affected storage is
metadata that C1.Excel doesn’t even use — only the name decoding crashes the whole load.
Suggested fix
Read the name as UTF-16LE directly, e.g.:
string name = Encoding.Unicode.GetString(entryBytes, 0, nameLengthInBytes - 2);
or construct the reader with new BinaryReader(memoryStream, Encoding.Unicode) and read one char per
2 bytes. Either removes the crash and decodes the names correctly.
Workaround I’m using (in case others hit this): copy the file bytes to memory, walk the CFB directory
sectors, replace non-ASCII UTF-16 code units in entry names with ‘_’, and pass the sanitized
MemoryStream to C1XLBook.Load(Stream). The workbook stream is untouched and loads fine afterwards.
