Errors, limits, and unknown values
CStructSharp gives expected layout and binary-operation failures stable categories. Application code can branch on the category while logs retain a more detailed message, path, offset, and inner exception.
Invalid layouts
Constructing CStruct checks syntax, names, types, finite storage, expressions, and preparation limits before any
binary input or output is accepted.
Examples that produce CStructLayoutException with InvalidLayout include:
- unsupported syntax or type forms;
- unknown or duplicate names;
- alias or definition cycles;
- recursive by-value storage;
- invalid enum backing/range;
- bitfield widths outside their storage;
- negative or overflowing array counts computed from constants alone; and
- source, nesting, dependency, or expression work above compilation limits.
A count or selector that fails only because of the data is not a layout error. When a decoded uint32 of
4294967295 selects an array count, or a * b overflows for the decoded values of a and b, the operation
fails with CStructReadException (ReadFailed) and a message such as
Cannot evaluate array length for data: 'n' is 4294967295, which is outside the 32-bit range that layout expressions support. A write that receives such a value fails with CStructWriteException.
A syntax error's message starts with Layout definition contains invalid syntax: and names the line and column of
the first unexpected character (or the end of the text) together with what the parser expected there.
An error about a declaration that parsed but cannot be compiled - an unknown type, a duplicate name, a by-value
recursion, a name that collides with a built-in codec - names the declaration and ends with its position, which
CStructLayoutException.Line and .Column also expose (one-based, counted over the text handed to CStruct,
prelude included). A type spelling made of several words whose first word is itself a type is almost always a
missing ;, and the message says so:
Unknown type 'uint16 kind uint32' for field 'length' in struct 'header'; a ';' may be missing after 'kind'. (line 2, column 3)
The Differences from C page lists 17 representative rejected C forms executed on both target frameworks.
Invalid method arguments are not layout errors. A null source, unsupported pointer width, or non-positive option
limit remains an argument exception. Do not catch every Exception and relabel it as malformed data.
Bounded failures
For a valid layout, operation options prevent untrusted data from requesting unlimited work:
| Limit area | Read result | Write result |
|---|---|---|
| Array count | ReadLimitExceeded |
WriteLimitExceeded |
| Encoded terminated string | ReadLimitExceeded |
WriteLimitExceeded |
| Total physical bytes | ReadLimitExceeded |
WriteLimitExceeded |
| Composite nesting | ReadLimitExceeded |
WriteLimitExceeded |
| Pointer depth/fixed target | ReadLimitExceeded |
Pointer range/shape uses WriteFailed |
| Malformed/truncated encoded bytes | ReadFailed |
Not applicable |
The bounded-failures fixture reads 41 42 00 as "AB" under normal settings, then repeats with
MaxStringBytes = 2 and requires ReadLimitExceeded. No partial value is returned.
Update path traversal has its own MaxTraversal* read limits. Those checks happen before staged replacement output
is committed.
Stable error categories
Every expected layout-operation failure derives from CStructException:
| Code | Exception | Meaning |
|---|---|---|
InvalidLayout (1) |
CStructLayoutException |
Source cannot become a valid finite Portable layout |
InvalidPath (2) |
CStructPathException |
Root, member, index, accessor, or checked path arithmetic is invalid |
ReadFailed (3) |
CStructReadException |
Input is truncated/malformed, a pointer is invalid/cyclic, or typed mapping fails |
ReadLimitExceeded (4) |
CStructReadLimitException |
A read/traversal ceiling was reached |
WriteFailed (5) |
CStructWriteException |
Payload, conversion, shape, encoding, pointer, union, or physical output failed |
WriteLimitExceeded (6) |
CStructWriteLimitException |
A write/output ceiling was reached |
Domain exceptions include a normalized Path and stream Offset when known. Their message and inner exception may
contain managed diagnostic detail. Invalid arguments, unsupported stream capabilities, cancellation, and unexpected
defects are not converted into these categories.
Branch on Code, not exact message text. Do not forward managed messages, inner exceptions, or DebugData unchanged
to an untrusted client; they may expose values and implementation details.
Unknown enum values
An enum number may be valid even when no declared member has that number. EnumValueResult keeps:
Valueas an exactBigInteger;RawBits,BitWidth,IsSigned, andStorageType;- the enum declaration name; and
Name, which is null for an unknown number.
Writers accept declared names, the eight CLR integral types, BigInteger, invariant decimal integer strings,
compatible parsed results, or consistent objects containing enum/name/value metadata. Boolean, fractional,
contradictory, and out-of-range values produce CStructWriteException.
See Handle errors and recovery for operation-specific recovery behavior and Preserve exact enum values for a runnable unknown-value example.