microsoft / microsoft/microsoft-ui-xaml

DirectUI.DirectUISchemaContext

Open Beginner friendly
#11,808 1 comment 0 reactions 0 assignees View on GitHub
area-XamlCompiler bug needs-author-feedback needs-repro team-Core team-Markup
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

## Summary

In the method `PropagateOutOfDateStatus(DirectUI.DirectUISchemaContext context)`,
a `using` block opens a `fileReader` stream but is missing curly braces `{}`.

As a result, the `using` scope ends immediately after the `if` condition is
evaluated. When `TryReadClassFullName` returns `false`, the code inside the
`if` block executes OUTSIDE the `using` scope — meaning `fileReader` is already
DISPOSED at that point.

Calling `XamlNodeStreamHelper.ReadXClassFromXamlFileStream(fileReader, context)`
on a disposed stream causes:
- `ObjectDisposedException` at runtime
- Silent data corruption (wrong class name cached)
- Incorrect incremental build decisions
- Full build corruption with NO visible error to developer

---

## Product / Component

- **Product:** Microsoft WinUI / Windows App SDK
- **Component:** XAML Build Tools — DirectUI.DirectUISchemaContext
- **Method:** PropagateOutOfDateStatus(DirectUI.DirectUISchemaContext context)
- **Language:** C#
- **Type:** Resource Management / Logic Error

---

## Severity

🔴 Critical — Silent build corruption, no visible error thrown in normal builds

---

## Root Cause

Missing curly braces `{}` after `using` statement causes incorrect scoping.
The compiler treats only the `if` statement as part of the `using` block.
The body of the `if` executes after `fileReader` is already disposed.

---

## Buggy Code

```csharp
// ❌ BUGGY CODE
using (var fileReader = TaskFileService.GetFileContents(tif.SourceXamlFullPath))
if (!TryReadClassFullName(tif, context, out newClassFullName))
{
// fileReader is ALREADY DISPOSED here!
newClassFullName = XamlNodeStreamHelper
.ReadXClassFromXamlFileStream(fileReader, context);
continue;
}

### Why is this important?

This bug causes silent build corruption in the XAML incremental
build pipeline. When TryReadClassFullName returns false (malformed
XAML or unreadable file), the fileReader stream is already disposed
before ReadXClassFromXamlFileStream is called.

Impact:
- Wrong x:Class name gets cached silently — no error shown
- Incorrect code gets generated from XAML files
- Incremental build makes wrong decisions causing full rebuilds
- Developer has NO indication that build output is corrupted
- Only triggers on malformed XAML or file read failure —
very hard to detect in normal builds

### Steps to reproduce the bug

1. Set up a WinUI / Windows App SDK project with XAML files
2. Create a XAML file with malformed markup OR a file that
causes TryReadClassFullName to return false
3. Trigger an incremental build so PropagateOutOfDateStatus
method is called
4. Observe: Either ObjectDisposedException is thrown OR
incorrect x:Class name is silently cached with no error

### Actual behavior

fileReader stream is disposed BEFORE ReadXClassFromXamlFileStream
is called due to missing curly braces {} after the using statement.

Result:
- ObjectDisposedException thrown at runtime, OR
- Wrong x:Class name silently cached in build system
- Build corrupted with zero visible error to developer

### Expected behavior

fileReader stream should remain open and valid when
ReadXClassFromXamlFileStream is called.

Fix — Add curly braces {} after using block:

using (var fileReader = TaskFileService
.GetFileContents(tif.SourceXamlFullPath))
{
if (!TryReadClassFullName(tif, context, out newClassFullName))
{
newClassFullName = XamlNodeStreamHelper
.ReadXClassFromXamlFileStream(fileReader, context);
continue;
}
}

### Screenshots

No screenshot available.
Bug identified through static code analysis of publicly
visible code diff on Microsoft Learn Q&A:
https://learn.microsoft.com/en-in/answers/questions/5897494/troubleshooting-microsoft-external-id-custom-authe

### NuGet package version

Not applicable — bug identified through code diff analysis

### Windows version

Windows 11 (24H2): Build 26120, Windows 11 (24H2): Build 26100

### Additional context

Bug was identified through static code analysis of a publicly
visible code diff posted on Microsoft Learn Q&A forum.

Root Cause:
Missing curly braces {} after using statement in
PropagateOutOfDateStatus method causes fileReader to be
disposed before ReadXClassFromXamlFileStream is called.

Secondary Issue:
catch (Exception) is too broad — silently swallows all
exceptions including critical ones like OutOfMemoryException.
Should be replaced with specific exception types (IOException,
XamlParseException) with proper logging.

Fix Required:
Add {} curly braces around using block body — 2 line fix.

Reference:
https://learn.microsoft.com/en-in/answers/questions/5897494/troubleshooting-microsoft-external-id-custom-authe

This is NOT a security vulnerability.
This is a build correctness bug.

Contributor guide

Open the contributing guide

Research direction

Search the repository for PropagateOutOfDateStatus in DirectUI.DirectUISchemaContext and inspect the using scope around fileReader. Ensure the stream remains valid through ReadXClassFromXamlFileStream, then run the relevant XAML incremental build or existing validation path to confirm the malformed or unreadable-file case behaves correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
build-system, desktop
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.