diff --git a/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx b/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx
index d21fc81878c..3bc3fa774f7 100644
--- a/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx
+++ b/web/app/components/base/markdown-blocks/__tests__/form.spec.tsx
@@ -534,6 +534,26 @@ describe('MarkdownForm', () => {
// Unicode letters should be valid form field names.
describe('Unicode name support', () => {
+ it('should include fields whose names contain supported full-width and half-width punctuation', async () => {
+ const user = userEvent.setup()
+ const node = createRootNode(
+ [
+ createElementNode('input', { type: 'hidden', name: '字段()!*&-', value: 'full-width' }),
+ createElementNode('input', { type: 'hidden', name: 'field()!*&-', value: 'half-width' }),
+ createElementNode('button', {}, [createTextNode('Submit')]),
+ ],
+ { dataFormat: 'json' },
+ )
+
+ render()
+
+ await user.click(screen.getByRole('button', { name: 'Submit' }))
+
+ await waitFor(() => {
+ expect(mockOnSend).toHaveBeenCalledWith('{"字段()!*&-":"full-width","field()!*&-":"half-width"}')
+ })
+ })
+
it('should include Unicode-named fields from all supported controls in JSON output', async () => {
const user = userEvent.setup()
const node = createRootNode(
diff --git a/web/app/components/base/markdown-blocks/form.tsx b/web/app/components/base/markdown-blocks/form.tsx
index 46a3ef5d9ea..1d1825dc7ef 100644
--- a/web/app/components/base/markdown-blocks/form.tsx
+++ b/web/app/components/base/markdown-blocks/form.tsx
@@ -43,7 +43,7 @@ const SUPPORTED_TYPES_SET = new Set(Object.values(SUPPORTED_TYPES))
const SAFE_NAME_RE = (() => {
try {
- return new RegExp('^\\p{L}[\\p{L}\\p{M}\\p{N}_-]*$', 'u')
+ return new RegExp('^\\p{L}[\\p{L}\\p{M}\\p{N}_()!*&()!*&--]*$', 'u')
}
catch {
// Fallback for browsers without Unicode property escape support.