From 943e5cea7ff65dff7fefa7ec4ec61e3b32d9c7de Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 13 May 2026 04:08:49 +0000 Subject: [PATCH 1/3] release: applying package updates - web-components --- ...-efc149c5-3d43-4300-a413-b3d9048e2248.json | 7 --- ...-38caae0f-3c50-46f0-b0c2-bb87de96d641.json | 7 --- ...-669e37a5-2c7c-4b19-95d4-8b070c6d72f7.json | 7 --- ...-80c47489-fa3b-4929-8f16-f8ff8d79b89f.json | 7 --- ...-962383bb-b75c-46a4-bc98-038f6dd7f558.json | 7 --- ...-bc13b7de-bb06-4180-a517-c64ffe612490.json | 7 --- ...-c28cec00-7029-4430-8cf5-17143006a866.json | 7 --- ...-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json | 7 --- .../chart-web-components/CHANGELOG.json | 21 ++++++++ .../charts/chart-web-components/CHANGELOG.md | 12 ++++- .../charts/chart-web-components/package.json | 4 +- packages/web-components/CHANGELOG.json | 53 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 15 +++++- packages/web-components/package.json | 2 +- 14 files changed, 102 insertions(+), 61 deletions(-) delete mode 100644 change/@fluentui-chart-web-components-efc149c5-3d43-4300-a413-b3d9048e2248.json delete mode 100644 change/@fluentui-web-components-38caae0f-3c50-46f0-b0c2-bb87de96d641.json delete mode 100644 change/@fluentui-web-components-669e37a5-2c7c-4b19-95d4-8b070c6d72f7.json delete mode 100644 change/@fluentui-web-components-80c47489-fa3b-4929-8f16-f8ff8d79b89f.json delete mode 100644 change/@fluentui-web-components-962383bb-b75c-46a4-bc98-038f6dd7f558.json delete mode 100644 change/@fluentui-web-components-bc13b7de-bb06-4180-a517-c64ffe612490.json delete mode 100644 change/@fluentui-web-components-c28cec00-7029-4430-8cf5-17143006a866.json delete mode 100644 change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json diff --git a/change/@fluentui-chart-web-components-efc149c5-3d43-4300-a413-b3d9048e2248.json b/change/@fluentui-chart-web-components-efc149c5-3d43-4300-a413-b3d9048e2248.json deleted file mode 100644 index e7def50970997e..00000000000000 --- a/change/@fluentui-chart-web-components-efc149c5-3d43-4300-a413-b3d9048e2248.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "patch", - "comment": "fix: update fast-element dependency version", - "packageName": "@fluentui/chart-web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-38caae0f-3c50-46f0-b0c2-bb87de96d641.json b/change/@fluentui-web-components-38caae0f-3c50-46f0-b0c2-bb87de96d641.json deleted file mode 100644 index 9e94b949c3f1ed..00000000000000 --- a/change/@fluentui-web-components-38caae0f-3c50-46f0-b0c2-bb87de96d641.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: remove hoisted peer dependency entries", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-669e37a5-2c7c-4b19-95d4-8b070c6d72f7.json b/change/@fluentui-web-components-669e37a5-2c7c-4b19-95d4-8b070c6d72f7.json deleted file mode 100644 index f103de031e7866..00000000000000 --- a/change/@fluentui-web-components-669e37a5-2c7c-4b19-95d4-8b070c6d72f7.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: enhance accessibility attributes for drawer component", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-80c47489-fa3b-4929-8f16-f8ff8d79b89f.json b/change/@fluentui-web-components-80c47489-fa3b-4929-8f16-f8ff8d79b89f.json deleted file mode 100644 index b6ae232147899a..00000000000000 --- a/change/@fluentui-web-components-80c47489-fa3b-4929-8f16-f8ff8d79b89f.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix keyboard navigation regressions for tree and menu-list", - "packageName": "@fluentui/web-components", - "email": "machi@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-962383bb-b75c-46a4-bc98-038f6dd7f558.json b/change/@fluentui-web-components-962383bb-b75c-46a4-bc98-038f6dd7f558.json deleted file mode 100644 index fd3625aedc557d..00000000000000 --- a/change/@fluentui-web-components-962383bb-b75c-46a4-bc98-038f6dd7f558.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "test: add tests for compound-button, dialog-body, drawer-body, menu-button, and menu-item components", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-bc13b7de-bb06-4180-a517-c64ffe612490.json b/change/@fluentui-web-components-bc13b7de-bb06-4180-a517-c64ffe612490.json deleted file mode 100644 index 059d9e20d1efd2..00000000000000 --- a/change/@fluentui-web-components-bc13b7de-bb06-4180-a517-c64ffe612490.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: synchronize compound-button template with button template", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-c28cec00-7029-4430-8cf5-17143006a866.json b/change/@fluentui-web-components-c28cec00-7029-4430-8cf5-17143006a866.json deleted file mode 100644 index cd2eda4e6017d8..00000000000000 --- a/change/@fluentui-web-components-c28cec00-7029-4430-8cf5-17143006a866.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: enhance accessibility attributes for dialog component", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json b/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json deleted file mode 100644 index 0da3e221a3ffce..00000000000000 --- a/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore: use component tag names in playwright tests", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/packages/charts/chart-web-components/CHANGELOG.json b/packages/charts/chart-web-components/CHANGELOG.json index e3bc2f7aee0b1d..9b7cc07a73d608 100644 --- a/packages/charts/chart-web-components/CHANGELOG.json +++ b/packages/charts/chart-web-components/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "@fluentui/chart-web-components", "entries": [ + { + "date": "Wed, 13 May 2026 04:08:42 GMT", + "tag": "@fluentui/chart-web-components_v0.0.77", + "version": "0.0.77", + "comments": { + "patch": [ + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/chart-web-components", + "commit": "e5b0e2412175216210360fee356a404af60f38d5", + "comment": "fix: update fast-element dependency version" + }, + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-rc.19", + "commit": "193b721bfced61e2faa1293118b8ff086634a317" + } + ] + } + }, { "date": "Mon, 11 May 2026 04:09:08 GMT", "tag": "@fluentui/chart-web-components_v0.0.76", diff --git a/packages/charts/chart-web-components/CHANGELOG.md b/packages/charts/chart-web-components/CHANGELOG.md index d4680bb2f4e238..ce287fde7c63e5 100644 --- a/packages/charts/chart-web-components/CHANGELOG.md +++ b/packages/charts/chart-web-components/CHANGELOG.md @@ -1,9 +1,19 @@ # Change Log - @fluentui/chart-web-components -This log was last generated on Mon, 11 May 2026 04:09:08 GMT and should not be manually modified. +This log was last generated on Wed, 13 May 2026 04:08:42 GMT and should not be manually modified. +## [0.0.77](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.77) + +Wed, 13 May 2026 04:08:42 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.76..@fluentui/chart-web-components_v0.0.77) + +### Patches + +- fix: update fast-element dependency version ([PR #36184](https://github.com/microsoft/fluentui/pull/36184) by 863023+radium-v@users.noreply.github.com) +- Bump @fluentui/web-components to v3.0.0-rc.19 ([PR #36199](https://github.com/microsoft/fluentui/pull/36199) by beachball) + ## [0.0.76](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.76) Mon, 11 May 2026 04:09:08 GMT diff --git a/packages/charts/chart-web-components/package.json b/packages/charts/chart-web-components/package.json index b190c9a5f06147..4805e96bfd8bf8 100644 --- a/packages/charts/chart-web-components/package.json +++ b/packages/charts/chart-web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/chart-web-components", "description": "A library of Fluent Chart Web Components", - "version": "0.0.76", + "version": "0.0.77", "author": { "name": "Microsoft" }, @@ -69,7 +69,7 @@ "dependencies": { "@microsoft/fast-web-utilities": "^6.0.0", "@fluentui/tokens": "^1.0.0-alpha.23", - "@fluentui/web-components": "^3.0.0-rc.18", + "@fluentui/web-components": "^3.0.0-rc.19", "@types/d3-selection": "^3.0.0", "@types/d3-shape": "^3.0.0", "d3-selection": "^3.0.0", diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index d26456c68d3969..a52aeda0575524 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,59 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 13 May 2026 04:08:40 GMT", + "tag": "@fluentui/web-components_v3.0.0-rc.19", + "version": "3.0.0-rc.19", + "comments": { + "prerelease": [ + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "e5b0e2412175216210360fee356a404af60f38d5", + "comment": "fix: remove hoisted peer dependency entries" + }, + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "28238ebebb45c41d0ec3df57003dbbe5fc422c6b", + "comment": "fix: enhance accessibility attributes for drawer component" + }, + { + "author": "machi@microsoft.com", + "package": "@fluentui/web-components", + "commit": "52fd89c25172001d37bc9e36a7b2f2587272edbe", + "comment": "fix keyboard navigation regressions for tree and menu-list" + }, + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "28238ebebb45c41d0ec3df57003dbbe5fc422c6b", + "comment": "fix: synchronize compound-button template with button template" + }, + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "28238ebebb45c41d0ec3df57003dbbe5fc422c6b", + "comment": "fix: enhance accessibility attributes for dialog component" + } + ], + "none": [ + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "28238ebebb45c41d0ec3df57003dbbe5fc422c6b", + "comment": "test: add tests for compound-button, dialog-body, drawer-body, menu-button, and menu-item components" + }, + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "6bc6e8c9ffabd0f970fb211bb924938064dce76e", + "comment": "chore: use component tag names in playwright tests" + } + ] + } + }, { "date": "Mon, 11 May 2026 04:09:08 GMT", "tag": "@fluentui/web-components_v3.0.0-rc.18", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index e87833183e54a8..288498cfb668af 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,22 @@ # Change Log - @fluentui/web-components -This log was last generated on Mon, 11 May 2026 04:09:08 GMT and should not be manually modified. +This log was last generated on Wed, 13 May 2026 04:08:40 GMT and should not be manually modified. +## [3.0.0-rc.19](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-rc.19) + +Wed, 13 May 2026 04:08:40 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-rc.18..@fluentui/web-components_v3.0.0-rc.19) + +### Changes + +- fix: remove hoisted peer dependency entries ([PR #36184](https://github.com/microsoft/fluentui/pull/36184) by 863023+radium-v@users.noreply.github.com) +- fix: enhance accessibility attributes for drawer component ([PR #36191](https://github.com/microsoft/fluentui/pull/36191) by 863023+radium-v@users.noreply.github.com) +- fix keyboard navigation regressions for tree and menu-list ([PR #36118](https://github.com/microsoft/fluentui/pull/36118) by machi@microsoft.com) +- fix: synchronize compound-button template with button template ([PR #36191](https://github.com/microsoft/fluentui/pull/36191) by 863023+radium-v@users.noreply.github.com) +- fix: enhance accessibility attributes for dialog component ([PR #36191](https://github.com/microsoft/fluentui/pull/36191) by 863023+radium-v@users.noreply.github.com) + ## [3.0.0-rc.18](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-rc.18) Mon, 11 May 2026 04:09:08 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 3064cc7dc3eaf4..4819d1d21e748b 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-rc.18", + "version": "3.0.0-rc.19", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 99955e344d7a0f6381f24d2b7cf4fbc06c4d6a32 Mon Sep 17 00:00:00 2001 From: v-baambati <132879294+v-baambati@users.noreply.github.com> Date: Wed, 13 May 2026 13:39:50 +0530 Subject: [PATCH 2/3] updated isSafeUrl function to fix network related attacks (#36121) --- ...-355a59ec-794a-4da2-93a6-ea28e5c1c204.json | 7 +++ ...-eede23c0-c45d-4f45-9a22-a7a9334860bb.json | 7 +++ .../src/utilities/UtilityUnitTests.test.ts | 47 +++++++++++++++++++ .../react-charting/src/utilities/utilities.ts | 6 +-- .../src/utilities/UtilityUnitTests.test.ts | 47 +++++++++++++++++++ .../library/src/utilities/utilities.ts | 5 +- 6 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 change/@fluentui-react-charting-355a59ec-794a-4da2-93a6-ea28e5c1c204.json create mode 100644 change/@fluentui-react-charts-eede23c0-c45d-4f45-9a22-a7a9334860bb.json diff --git a/change/@fluentui-react-charting-355a59ec-794a-4da2-93a6-ea28e5c1c204.json b/change/@fluentui-react-charting-355a59ec-794a-4da2-93a6-ea28e5c1c204.json new file mode 100644 index 00000000000000..fee447e608b149 --- /dev/null +++ b/change/@fluentui-react-charting-355a59ec-794a-4da2-93a6-ea28e5c1c204.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "safeurl related bug fix", + "packageName": "@fluentui/react-charting", + "email": "132879294+v-baambati@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-charts-eede23c0-c45d-4f45-9a22-a7a9334860bb.json b/change/@fluentui-react-charts-eede23c0-c45d-4f45-9a22-a7a9334860bb.json new file mode 100644 index 00000000000000..f1d8f42a9a98e3 --- /dev/null +++ b/change/@fluentui-react-charts-eede23c0-c45d-4f45-9a22-a7a9334860bb.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "safeurl related bug fix", + "packageName": "@fluentui/react-charts", + "email": "132879294+v-baambati@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts b/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts index 8cc45358358c6c..fc170e02ad09df 100644 --- a/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts +++ b/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts @@ -1523,6 +1523,10 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('https://example.com')).toBe(true); }); + test('Should allow https URL with leading whitespace', () => { + expect(utils.isSafeUrl(' https://example.com')).toBe(true); + }); + test('Should allow https URL with path, query, and fragment', () => { expect(utils.isSafeUrl('https://example.com/path?q=1#section')).toBe(true); }); @@ -1552,6 +1556,26 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('javascript:alert(1)')).toBe(false); }); + test('Should block javascript: protocol with leading whitespace', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl(' javascript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with leading tabs/newlines', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\n\tjavascript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with embedded newline in scheme', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('java\nscript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with embedded tab in scheme', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('java\tscript:alert(1)')).toBe(false); + }); + test('Should block data: protocol', () => { expect(utils.isSafeUrl('data:text/html,')).toBe(false); }); @@ -1560,6 +1584,25 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('vbscript:msgbox("xss")')).toBe(false); }); + test('Should block vbscript:alert(1)', () => { + expect(utils.isSafeUrl('vbscript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with null byte prefix', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\0javascript:alert(1)')).toBe(false); + }); + + test('Should block mixed-case javascript: protocol with embedded newline', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('JaVa\nScRiPt:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with CRLF prefix', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\r\njavascript:alert(1)')).toBe(false); + }); + test('Should block file: protocol', () => { expect(utils.isSafeUrl('file:///etc/passwd')).toBe(false); }); @@ -1580,6 +1623,10 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('custom:payload')).toBe(false); }); + test('Should block custom: protocol with leading whitespace', () => { + expect(utils.isSafeUrl(' custom:payload')).toBe(false); + }); + test('Should allow a path that contains a colon but is not a scheme', () => { expect(utils.isSafeUrl('/path/to:resource')).toBe(true); }); diff --git a/packages/charts/react-charting/src/utilities/utilities.ts b/packages/charts/react-charting/src/utilities/utilities.ts index eeae65c4af60bf..262e00eaf7a07e 100644 --- a/packages/charts/react-charting/src/utilities/utilities.ts +++ b/packages/charts/react-charting/src/utilities/utilities.ts @@ -2556,9 +2556,9 @@ const truncateTextToFitWidth = (text: string, maxWidth: number, measure: (s: str }; export function isSafeUrl(href: string): boolean { - if (/^[a-z][a-z0-9+.-]*:/i.test(href)) { - return /^(https?|mailto|tel|ftp):/i.test(href); + const normalized = href.replace(/[\u0000-\u001F\u007F\s]+/g, ''); + if (/^[a-z][a-z0-9+.-]*:/i.test(normalized)) { + return /^(https?|mailto|tel|ftp):/i.test(normalized); } - return true; } diff --git a/packages/charts/react-charts/library/src/utilities/UtilityUnitTests.test.ts b/packages/charts/react-charts/library/src/utilities/UtilityUnitTests.test.ts index 2237bf11890148..195f1c3820efee 100644 --- a/packages/charts/react-charts/library/src/utilities/UtilityUnitTests.test.ts +++ b/packages/charts/react-charts/library/src/utilities/UtilityUnitTests.test.ts @@ -1528,6 +1528,10 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('https://example.com')).toBe(true); }); + test('Should allow https URL with leading whitespace', () => { + expect(utils.isSafeUrl(' https://example.com')).toBe(true); + }); + test('Should allow https URL with path, query, and fragment', () => { expect(utils.isSafeUrl('https://example.com/path?q=1#section')).toBe(true); }); @@ -1557,6 +1561,26 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('javascript:alert(1)')).toBe(false); }); + test('Should block javascript: protocol with leading whitespace', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl(' javascript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with leading tabs/newlines', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\n\tjavascript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with embedded newline in scheme', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('java\nscript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with embedded tab in scheme', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('java\tscript:alert(1)')).toBe(false); + }); + test('Should block data: protocol', () => { expect(utils.isSafeUrl('data:text/html,')).toBe(false); }); @@ -1565,6 +1589,25 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('vbscript:msgbox("xss")')).toBe(false); }); + test('Should block vbscript:alert(1)', () => { + expect(utils.isSafeUrl('vbscript:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with null byte prefix', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\0javascript:alert(1)')).toBe(false); + }); + + test('Should block mixed-case javascript: protocol with embedded newline', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('JaVa\nScRiPt:alert(1)')).toBe(false); + }); + + test('Should block javascript: protocol with CRLF prefix', () => { + // eslint-disable-next-line no-script-url + expect(utils.isSafeUrl('\r\njavascript:alert(1)')).toBe(false); + }); + test('Should block file: protocol', () => { expect(utils.isSafeUrl('file:///etc/passwd')).toBe(false); }); @@ -1585,6 +1628,10 @@ describe('isSafeUrl', () => { expect(utils.isSafeUrl('custom:payload')).toBe(false); }); + test('Should block custom: protocol with leading whitespace', () => { + expect(utils.isSafeUrl(' custom:payload')).toBe(false); + }); + test('Should allow a path that contains a colon but is not a scheme', () => { expect(utils.isSafeUrl('/path/to:resource')).toBe(true); }); diff --git a/packages/charts/react-charts/library/src/utilities/utilities.ts b/packages/charts/react-charts/library/src/utilities/utilities.ts index 4d2249185fcadb..add89c7e9ceaa9 100644 --- a/packages/charts/react-charts/library/src/utilities/utilities.ts +++ b/packages/charts/react-charts/library/src/utilities/utilities.ts @@ -2716,8 +2716,9 @@ const truncateTextToFitWidth = (text: string, maxWidth: number, measure: (s: str }; export function isSafeUrl(href: string): boolean { - if (/^[a-z][a-z0-9+.-]*:/i.test(href)) { - return /^(https?|mailto|tel|ftp):/i.test(href); + const normalized = href.replace(/[\u0000-\u001F\u007F\s]+/g, ''); + if (/^[a-z][a-z0-9+.-]*:/i.test(normalized)) { + return /^(https?|mailto|tel|ftp):/i.test(normalized); } return true; } From aa64b59ef6f60ae8231f7ee738c914b36fa6755d Mon Sep 17 00:00:00 2001 From: Dmytro Kirpa Date: Wed, 13 May 2026 11:12:49 +0200 Subject: [PATCH 3/3] fix(react-card): avoid pulling griffel in base hooks (#36194) --- ...ui-react-card-c273bc2b-822e-4a34-bc44-57e000ac8bd5.json | 7 +++++++ .../library/src/components/CardHeader/useCardHeader.ts | 3 +-- .../library/src/components/CardPreview/useCardPreview.ts | 3 +-- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 change/@fluentui-react-card-c273bc2b-822e-4a34-bc44-57e000ac8bd5.json diff --git a/change/@fluentui-react-card-c273bc2b-822e-4a34-bc44-57e000ac8bd5.json b/change/@fluentui-react-card-c273bc2b-822e-4a34-bc44-57e000ac8bd5.json new file mode 100644 index 00000000000000..b448001b2a1131 --- /dev/null +++ b/change/@fluentui-react-card-c273bc2b-822e-4a34-bc44-57e000ac8bd5.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: avoid pulling griffel in CardHeader and CardPreview base hooks", + "packageName": "@fluentui/react-card", + "email": "dmytrokirpa@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-card/library/src/components/CardHeader/useCardHeader.ts b/packages/react-components/react-card/library/src/components/CardHeader/useCardHeader.ts index 3ea6100db21d20..25c46a8e13dd10 100644 --- a/packages/react-components/react-card/library/src/components/CardHeader/useCardHeader.ts +++ b/packages/react-components/react-card/library/src/components/CardHeader/useCardHeader.ts @@ -4,7 +4,6 @@ import * as React from 'react'; import { getIntrinsicElementProps, useId, slot } from '@fluentui/react-utilities'; import type { CardHeaderBaseProps, CardHeaderBaseState, CardHeaderProps, CardHeaderState } from './CardHeader.types'; import { useCardContext_unstable } from '../Card/CardContext'; -import { cardHeaderClassNames } from './useCardHeaderStyles.styles'; /** * Finds the first child of CardHeader with an id prop. @@ -77,7 +76,7 @@ export const useCardHeaderBase_unstable = ( const headerRef = React.useRef(null); const hasChildId = React.useRef(false); - const generatedId = useId(cardHeaderClassNames.header, referenceId); + const generatedId = useId('fui-CardHeader__header', referenceId); const headerSlot = slot.optional(header, { renderByDefault: true, diff --git a/packages/react-components/react-card/library/src/components/CardPreview/useCardPreview.ts b/packages/react-components/react-card/library/src/components/CardPreview/useCardPreview.ts index c05f066810fa01..6324ccf5aba464 100644 --- a/packages/react-components/react-card/library/src/components/CardPreview/useCardPreview.ts +++ b/packages/react-components/react-card/library/src/components/CardPreview/useCardPreview.ts @@ -9,7 +9,6 @@ import type { CardPreviewState, } from './CardPreview.types'; import { useCardContext_unstable } from '../Card/CardContext'; -import { cardPreviewClassNames } from './useCardPreviewStyles.styles'; /** * Create the state required to render CardPreview. @@ -52,7 +51,7 @@ export const useCardPreviewBase_unstable = ( } if (previewRef.current && previewRef.current.parentNode) { - const img = previewRef.current.parentNode.querySelector(`.${cardPreviewClassNames.root} > img`); + const img = previewRef.current.parentNode.querySelector(`.fui-CardPreview > img`); if (img) { const ariaLabel = img.getAttribute('aria-label');