Visitar URL original
Fix potential NREs when using AssertionScope (#3178) by dennisdoomen · Pull Request #3323 · fluentassertions/fluentassertions · GitHub
Skip to content

Fix potential NREs when using AssertionScope (#3178) - #3323

Merged
dennisdoomen merged 2 commits into
fluentassertions:mainfrom
dennisdoomen:fix-3178-assertionscope-nre
Aug 23, 2026
Merged

dennisdoomen merged 2 commits into
fluentassertions:mainfrom
dennisdoomen:fix-3178-assertionscope-nre

Conversation

@dennisdoomen

Copy link
Copy Markdown
Member

Fixes #3178

Problem

Several assertion methods followed this pattern:

assertionChain
    .ForCondition(subject is not null)
    .FailWith("... is <null>.")
    .Then
    .ForCondition(subject.Member)   // eagerly evaluated!
    .FailWith(...);

C# evaluates method arguments before invoking the method, so subject.Member is evaluated even when subject is null and the first condition already failed. Outside of an AssertionScope, the first failure throws immediately, so the chain never reaches the second line. Inside an AssertionScope, failures are only recorded (not thrown), so execution continues to the second .ForCondition(...), and evaluating subject.Member throws a NullReferenceException instead of producing a proper assertion failure message.

Fix

Replaced the eager dereferences with null-conditional comparisons (e.g. subject?.Member == true), following the pattern already used in TimeOnlyAssertions.cs. Also made a failure message in TypeAssertions.HaveProperty lazy, since it referenced propertyInfo.Name even when propertyInfo could be null.

Affected members

  • PropertyInfoAssertions: BeVirtual, NotBeVirtual, BeWritable (both overloads), NotBeWritable, BeReadable (both overloads), NotBeReadable, Return, NotReturn
  • TypeAssertions: HaveProperty, HaveIndexer

Testing

  • Added regression tests that wrap each affected assertion in an AssertionScope, reproducing the exact scenario from the issue.
  • Full FluentAssertions.Specs suite passes: 5963/5963 (net8.0).
  • Targeted PropertyInfoAssertionSpecs/TypeAssertionSpecs pass on net47, net6.0, and net8.0 (402/402 each).

No public API changes, so no API-approval step is required.

Several assertion methods evaluated a member of a possibly-null subject as part of the argument to a chained ForCondition call. Outside of an AssertionScope, an earlier failure throws immediately so the chain never reaches this point. But inside an AssertionScope, execution continues, and the eager dereference throws a NullReferenceException instead of producing a proper assertion failure message.

Fixed by using null-conditional comparisons (subject?.Member == expected) instead of eager dereferences, and by making a failure message in TypeAssertions.HaveProperty lazy so it isn't evaluated when the property doesn't exist.

Affected members:
- PropertyInfoAssertions: BeVirtual, NotBeVirtual, BeWritable (both overloads), NotBeWritable, BeReadable (both overloads), NotBeReadable, Return, NotReturn
- TypeAssertions: HaveProperty, HaveIndexer

Added regression tests wrapping the affected assertions in an AssertionScope, and a releases.md entry.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread docs/_pages/releases.md Resolved
Comment thread docs/_pages/releases.md Resolved
… release note

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Qodana for .NET

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Contact Qodana team

Contact us at qodana-support@jetbrains.com

@dennisdoomen dennisdoomen added this to the 8.11 milestone Aug 23, 2026
@dennisdoomen
dennisdoomen merged commit 55ce1f5 into fluentassertions:main Aug 23, 2026
11 of 12 checks passed
@dennisdoomen
dennisdoomen deleted the fix-3178-assertionscope-nre branch August 23, 2026 09:57
This was referenced Sep 14, 2026
This was referenced Nov 12, 2026

This branch was previously deployed

1 inactive deployment
qodana-pr — e50d3296 Deployed Aug 23, 2026 by dennisdoomen via Qodana Scan #139
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Potential NREs when using AssertionScope

2 participants