Skip to content

Conversation

@medhatiwari
Copy link
Contributor

Summary

Fixes test failures on big-endian architectures (s390x) by checking FrameType before accessing ComponentId in RendererTest.

Tests Fixed

  • QueuedRenderIsSkippedIfComponentWasAlreadyDisposedInSameBatch

Problem

Test was failing on s390x with System.InvalidOperationException: Sequence contains more than one element.

Root Cause

Field Overlap in RenderTreeFrame

RenderTreeFrame uses explicit struct layout with overlapping fields:

[StructLayout(LayoutKind.Explicit, Pack = 4)]
public struct RenderTreeFrame
{
    [FieldOffset(8)]  internal ulong AttributeEventHandlerIdField;  // 8 bytes: offset 8-15
    [FieldOffset(12)] internal int ComponentIdField;                // 4 bytes: offset 12-15
    // These fields OVERLAP at offset 12-15!
}

API Contract

The API documentation at RenderTreeFrame.cs:161-165 clearly states:

/// <summary>
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Component"/>,
/// gets the child component instance identifier.
/// </summary>
public int ComponentId => ComponentIdField;

The test accessed ComponentId without first checking FrameType == Component, violating this documented precondition.

Why It Failed on s390x (Big-Endian)

Due to the field overlap at offset 12-15, endianness affects what value is read:

Architecture Endianness AttributeEventHandlerId=1 Memory Layout ComponentId reads as
x64, ppc64le Little 1 01 00 00 00 00 00 00 00 0 (upper bytes)
s390x Big 1 00 00 00 00 00 00 00 01 1 (lower bytes)

On little-endian: Reading ComponentId from an Attribute frame returns 0 (bug hidden)
On big-endian: Reading ComponentId from an Attribute frame returns the AttributeEventHandlerId value (bug exposed)

Change 2: Fix same pattern preventively

File: src/Components/Components/test/RendererTest.cs

- var childComponent3 = batch.ReferenceFrames.Where(f => f.ComponentId == 3)
+ var childComponent3 = batch.ReferenceFrames.Where(f => f.FrameType == RenderTreeFrameType.Component && f.ComponentId == 3)
      .Single().Component;

Test: RenderBatchIncludesListOfDisposedComponents
Status: Not currently failing, but uses the same incorrect pattern

cc: @giritrivedi

Two tests accessed ComponentId without validating FrameType == Component,
violating the API contract (RenderTreeFrame.cs:161-165). This causes
regressions on big-endian architectures (s390x).
@medhatiwari medhatiwari requested a review from a team as a code owner October 24, 2025 08:18
@github-actions github-actions bot added the area-blazor Includes: Blazor, Razor Components label Oct 24, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Oct 24, 2025
@ilonatommy ilonatommy merged commit 9a5e663 into dotnet:main Oct 29, 2025
31 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 11.0-preview1 milestone Oct 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants