From 9e7e475bc0ad03d91a2879fbea7864f424820f96 Mon Sep 17 00:00:00 2001 From: rtmalikian Date: Fri, 19 Jun 2026 21:11:48 -0700 Subject: [PATCH] fix: add null-safety checks in ValidateController.ProcessResource() Prevent NullReferenceException when Parameters resource has: - Null Parameter collection - No 'resource' parameter - 'resource' parameter with null Resource property Matches the null-safety pattern from PR #5115 (ParameterCompatibleFilter). Fixes #5627 Signed-off-by: rtmalikian --- .../Controllers/ValidateControllerTests.cs | 40 +++++++++++++++++++ .../Controllers/ValidateController.cs | 10 +++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Health.Fhir.Shared.Api.UnitTests/Controllers/ValidateControllerTests.cs b/src/Microsoft.Health.Fhir.Shared.Api.UnitTests/Controllers/ValidateControllerTests.cs index 2195d8af99..4d901a777d 100644 --- a/src/Microsoft.Health.Fhir.Shared.Api.UnitTests/Controllers/ValidateControllerTests.cs +++ b/src/Microsoft.Health.Fhir.Shared.Api.UnitTests/Controllers/ValidateControllerTests.cs @@ -206,6 +206,46 @@ await _mediator.Received(valid && getResource ? 1 : 0).Send Arg.Any()); } + [Fact] + public async Task GivenParametersWithNullParameterCollection_WhenValidating_ThenShouldNotThrowNullReferenceException() + { + var parameters = new Parameters(); + parameters.Parameter = null; + + // Should not throw NullReferenceException; ProcessResource should handle gracefully + await _controller.Validate(parameters, null); + } + + [Fact] + public async Task GivenParametersWithMissingResourceParameter_WhenValidating_ThenShouldNotThrowNullReferenceException() + { + var parameters = new Parameters(); + parameters.Parameter.Add( + new Parameters.ParameterComponent() + { + Name = "otherParam", + Value = new FhirString("test"), + }); + + // Should not throw NullReferenceException; ProcessResource should handle gracefully + await _controller.Validate(parameters, null); + } + + [Fact] + public async Task GivenParametersWithNullResourceParameter_WhenValidating_ThenShouldNotThrowNullReferenceException() + { + var parameters = new Parameters(); + parameters.Parameter.Add( + new Parameters.ParameterComponent() + { + Name = "resource", + Resource = null, + }); + + // Should not throw NullReferenceException; ProcessResource should handle gracefully + await _controller.Validate(parameters, null); + } + private ICollection CreateIssues(int count) { var issues = new List(); diff --git a/src/Microsoft.Health.Fhir.Shared.Api/Controllers/ValidateController.cs b/src/Microsoft.Health.Fhir.Shared.Api/Controllers/ValidateController.cs index 9f262273ce..cfed7712f6 100644 --- a/src/Microsoft.Health.Fhir.Shared.Api/Controllers/ValidateController.cs +++ b/src/Microsoft.Health.Fhir.Shared.Api/Controllers/ValidateController.cs @@ -54,10 +54,10 @@ public async Task Validate([FromBody] Resource resource, [FromQue private static void ProcessResource(ref Resource resource, ref string profile) { - if (resource.TypeName == KnownResourceTypes.Parameters) + if (resource?.TypeName == KnownResourceTypes.Parameters) { var parameterResource = (Parameters)resource; - var profileFromParameters = parameterResource.Parameter.Find(param => param.Name.Equals("profile", StringComparison.OrdinalIgnoreCase)); + var profileFromParameters = parameterResource.Parameter?.Find(param => param.Name.Equals("profile", StringComparison.OrdinalIgnoreCase)); if (profileFromParameters != null) { if (profile != null) @@ -71,7 +71,11 @@ private static void ProcessResource(ref Resource resource, ref string profile) } } - resource = parameterResource.Parameter.Find(param => param.Name.Equals("resource", StringComparison.OrdinalIgnoreCase)).Resource; + var resourceParam = parameterResource.Parameter?.Find(param => param.Name.Equals("resource", StringComparison.OrdinalIgnoreCase)); + if (resourceParam?.Resource != null) + { + resource = resourceParam.Resource; + } } }