From ff213673f153ab336d278b430fd9316351dddd56 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 28 Oct 2026 18:47:05 +0500 Subject: [PATCH] http: validate arguments of response header methods --- docs/articles/migrate-to-v2.md | 3 ++ src/Ramstack.HtmxToolkit/HtmxResponse.cs | 43 ++++++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/docs/articles/migrate-to-v2.md b/docs/articles/migrate-to-v2.md index aaa56ef..0e41b36 100644 --- a/docs/articles/migrate-to-v2.md +++ b/docs/articles/migrate-to-v2.md @@ -466,6 +466,9 @@ These changes affect fewer applications: - `HtmxHeaderTagHelper.Headers` changed from `Dictionary` to `IDictionary`, and header names are compared without case. - `HtmxScrollBehavior` gained `Instant`. +- `Location`, `Redirect`, `Reswap(string)`, `Retarget`, and `Reselect` throw `ArgumentException` for a `null` + or empty value, and `Location(string, HtmxLocationOptions)` also throws for `null` options. + In 1.x, an empty value produced an empty header. - Generated JSON in attributes keeps non-ASCII characters, such as Cyrillic, instead of escaping them as `\uXXXX`. Update snapshot tests that compare it as text. diff --git a/src/Ramstack.HtmxToolkit/HtmxResponse.cs b/src/Ramstack.HtmxToolkit/HtmxResponse.cs index 634e62b..943b6fa 100644 --- a/src/Ramstack.HtmxToolkit/HtmxResponse.cs +++ b/src/Ramstack.HtmxToolkit/HtmxResponse.cs @@ -45,8 +45,12 @@ internal HtmxResponse(HttpResponse response) => /// /// The current instance. /// - public HtmxResponse Location(string value) => - SetHeader(this, HtmxResponseHeaderNames.Location, value); + public HtmxResponse Location(string value) + { + Argument.ThrowIfNullOrEmpty(value); + + return SetHeader(this, HtmxResponseHeaderNames.Location, value); + } /// /// Sets the HX-Location header to perform a client-side redirect @@ -59,6 +63,9 @@ public HtmxResponse Location(string value) => /// public HtmxResponse Location(string path, HtmxLocationOptions options) { + Argument.ThrowIfNullOrEmpty(path); + Argument.ThrowIfNull(options); + return LocationImpl(this, path, options); static HtmxResponse LocationImpl(HtmxResponse response, string path, HtmxLocationOptions options) @@ -159,8 +166,12 @@ public HtmxResponse PreventHistoryUpdate() => /// /// The current instance. /// - public HtmxResponse Redirect(string value) => - SetHeader(this, HtmxResponseHeaderNames.Redirect, value); + public HtmxResponse Redirect(string value) + { + Argument.ThrowIfNullOrEmpty(value); + + return SetHeader(this, HtmxResponseHeaderNames.Redirect, value); + } /// /// Sets the HX-Refresh header to request a full-page refresh. @@ -188,8 +199,12 @@ public HtmxResponse Reswap(HtmxSwap value) => /// /// The current instance. /// - public HtmxResponse Reswap(string value) => - SetHeader(this, HtmxResponseHeaderNames.Reswap, value); + public HtmxResponse Reswap(string value) + { + Argument.ThrowIfNullOrEmpty(value); + + return SetHeader(this, HtmxResponseHeaderNames.Reswap, value); + } /// /// Sets the HX-Retarget header to change the target of the content update @@ -199,8 +214,12 @@ public HtmxResponse Reswap(string value) => /// /// The current instance. /// - public HtmxResponse Retarget(string value) => - SetHeader(this, HtmxResponseHeaderNames.Retarget, value); + public HtmxResponse Retarget(string value) + { + Argument.ThrowIfNullOrEmpty(value); + + return SetHeader(this, HtmxResponseHeaderNames.Retarget, value); + } /// /// Sets the HX-Reselect header to select the part of the response to swap in. @@ -209,8 +228,12 @@ public HtmxResponse Retarget(string value) => /// /// The current instance. /// - public HtmxResponse Reselect(string value) => - SetHeader(this, HtmxResponseHeaderNames.Reselect, value); + public HtmxResponse Reselect(string value) + { + Argument.ThrowIfNullOrEmpty(value); + + return SetHeader(this, HtmxResponseHeaderNames.Reselect, value); + } /// /// Adds a client-side event to the response header selected by .