Skip to content

Commit

Permalink
Valid HTML Input name in FormInputElementPart (#17567)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek authored Mar 9, 2025
1 parent dbc9048 commit bca5bc7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.Extensions.Localization;
using OrchardCore.ContentManagement.Display.ContentDisplay;
using OrchardCore.ContentManagement.Display.Models;
using OrchardCore.ContentManagement.Utilities;
using OrchardCore.DisplayManagement.Views;
using OrchardCore.Forms.Models;
using OrchardCore.Forms.ViewModels;
Expand Down Expand Up @@ -35,8 +36,17 @@ public override async Task<IDisplayResult> UpdateAsync(FormInputElementPart part
{
context.Updater.ModelState.AddModelError(Prefix, nameof(viewModel.Name), S["A value is required for Name."]);
}
else
{
var safeName = viewModel.Name.GetSafeHTMLInputName();

if (viewModel.Name != safeName)
{
context.Updater.ModelState.AddModelError(Prefix, nameof(viewModel.Name), S["A Name contains invalid characters."]);
}
}

part.Name = viewModel.Name?.Trim();
part.Name = viewModel.Name;
part.ContentItem.DisplayText = part.Name;

return Edit(part, context);
Expand Down
17 changes: 12 additions & 5 deletions src/OrchardCore.Modules/OrchardCore.Forms/Migrations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,21 @@ await _contentDefinitionManager.AlterPartDefinitionAsync("FormPart", part => par

await _contentDefinitionManager.AlterTypeDefinitionAsync("Form", type => type
.WithPart("TitlePart", part => part
.WithSettings(new TitlePartSettings { RenderTitle = false })
.WithSettings(new TitlePartSettings
{
RenderTitle = false,
})
.WithPosition("0")
)
.WithPart("FormElementPart", part =>
part.WithPosition("1")
.WithPart("FormElementPart", part => part
.WithPosition("1")
)
.WithPart("FormPart", part => part
.WithPosition("2")
)
.WithPart("FlowPart", part => part
.WithPosition("3")
)
.WithPart("FormPart")
.WithPart("FlowPart")
.Stereotype("Widget"));

// FormElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
@model FormInputElementPartEditViewModel

<div class="@Orchard.GetWrapperClasses()">
<label asp-for="Name" class="@Orchard.GetLabelClasses()">@T["Name"]</label>
<label asp-for="Name" class="@Orchard.GetLabelClasses()">@T["HTML Name"]</label>
<div class="@Orchard.GetEndClasses()">
<input asp-for="Name" type="text" class="form-control content-preview-text content-caption-text" />
<span class="hint">@T["The name to render on this form element."]</span>
<span class="hint">@T["The valid characters for the HTML input name attribute are letters (a-z, A-Z), digits (0-9), hyphen (-), underscore (_), period (.), and square brackets ([ ])."]</span>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -385,4 +385,27 @@ public static string ReplaceLastOccurrence(this string source, string searchedVa

return source.Remove(lastIndex, searchedValue.Length).Insert(lastIndex, replacedValue);
}

private const string _validHtmlInputNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.[]";

public static string GetSafeHTMLInputName(this string input)
{
ArgumentException.ThrowIfNullOrEmpty(input);

var inputSpan = input.AsSpan();

var sanitizedName = new StringBuilder(inputSpan.Length);

foreach (var c in inputSpan)
{
if (!_validHtmlInputNameCharacters.Contains(c))
{
continue;
}

sanitizedName.Append(c);
}

return sanitizedName.ToString();
}
}

0 comments on commit bca5bc7

Please sign in to comment.