Skip to content

Fix nested annotation element encoding in StubGenerator (#724) - #725

Open
wasabii wants to merge 1 commit into
mainfrom
fix/issue-724-nested-annotation-encoding
Open

Fix nested annotation element encoding in StubGenerator (#724)#725
wasabii wants to merge 1 commit into
mainfrom
fix/issue-724-nested-annotation-encoding

Conversation

@wasabii

@wasabii wasabii commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #724.

The bug

StubGenerator.EncodeElementValue (the object overload) encodes a nested annotation (TAG_ANNOTATION) whose payload is laid out as name/value pairs: [tag, typeName, name0, value0, name1, value1, …]. The loop advanced by one instead of two:

for (int i = 2; i < v.Length; i++)   // wrong
    e2.Element(builder.Constants.GetOrAddUtf8((string)v[i]), e3 => EncodeElementValue(builder, ref e3, v[i + 1]));

After the first pair, i lands on a value slot, and (string)v[i] throws InvalidCastException: Unable to cast object of type 'System.Object[]' to type 'System.String' whenever that value is itself an array (a nested annotation, enum, or array member). It only fires for nested annotations with more than one element, which is why it went unnoticed for so long.

The fix

One character — i++i += 2 — restoring parity with the two sibling loops that were ported correctly (EncodeAnnotation and the CustomAttributeTypedArgument overload) and with the pre-rewrite implementation.

History

Regression introduced in 3dad0f9 (Aug 18 2024), the rewrite of StubGen onto IKVM.ByteCode. The old WriteAnnotationElementValue used i += 2; the rewrite produced three copies of the pattern and two of the three kept the increment. This one didn't.

The object-overload of EncodeElementValue iterated a nested annotation's
name/value pairs with i++ instead of i += 2. After the first pair, i lands
on a value slot, so (string)v[i] throws InvalidCastException when the value
is an array (nested annotation, enum, or array member).

This was a porting typo introduced in 3dad0f9 when StubGen was rewritten
on top of IKVM.ByteCode; the pre-rewrite loop and the two sibling loops
(EncodeAnnotation and the CustomAttributeTypedArgument overload) all use
i += 2 correctly.

Fixes #724
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.InvalidCastException: 'Unable to cast object of type 'System.Object[]' to type 'System.String'.'

1 participant