Skip to content

[chat] Normalize message part link URLs#23187

Merged
hasdfa merged 4 commits into
mui:masterfrom
hasdfa:agent/sanitize-chat-message-links
Jul 21, 2026
Merged

[chat] Normalize message part link URLs#23187
hasdfa merged 4 commits into
mui:masterfrom
hasdfa:agent/sanitize-chat-message-links

Conversation

@hasdfa

@hasdfa hasdfa commented Jul 20, 2026

Copy link
Copy Markdown
Member

Changelog

Use the existing URI normalization helper for file and source link targets.

These renderers previously passed link targets directly instead of using the helper already available in x-chat-headless. This keeps link handling consistent across the built-in component and fallback renderer paths, while preserving supported URLs as-is.

Test plan

  • pnpm test:unit --project "x-chat-headless" --run

  • pnpm test:browser --project "x-chat-headless" --run packages/x-chat-headless/src/message/parts/MessageParts.test.tsx

  • pnpm --filter "@mui/x-chat-headless" run typescript

  • pnpm eslint

  • I have followed (at least) the PR section of the contributing guide.

@code-infra-dashboard

code-infra-dashboard Bot commented Jul 20, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-23187--material-ui-x.netlify.app/
QR code for https://deploy-preview-23187--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 0B(0.00%) 0B(0.00%)
@mui/x-chat 🔺+500B(+0.16%) 🔺+172B(+0.19%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@hasdfa
hasdfa marked this pull request as ready for review July 20, 2026 16:35
Copilot AI review requested due to automatic review settings July 20, 2026 16:35
@hasdfa hasdfa self-assigned this Jul 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hasdfa hasdfa added type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. scope: chat Changes related to the AI chat. labels Jul 20, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 12d72fd5b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<Root {...rootProps}>
<LinkSlot href={part.url} rel="noreferrer noopener" target="_blank" {...linkProps}>
<LinkSlot
href={safeUri(part.url) || undefined}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve blob URLs for file parts

When a user sends an attachment, useChatComposer builds file parts with url: attachment.previewUrl ?? URL.createObjectURL(...) (packages/x-chat-headless/src/hooks/useChatComposer.ts:191-196), and the tests cover non-image blob:hello.txt attachments. safeUri only allows http/https/mailto/tel and relative URLs (partUtils.ts:34-40), so blob: is converted to '' here and the rendered anchor loses its href; sent text/PDF attachments become inert filenames instead of clickable/downloadable file links. The fallback renderDefaultFilePart has the same new call, so file parts should either allow safe blob: URLs or avoid applying this sanitizer to file attachment links.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 297b10b. File-part links now use a dedicated URL policy that preserves only same-origin blob URLs; cross-origin and opaque-origin blob URLs still render without an href. Source URL renderers keep the existing stricter policy. Added coverage for both FilePart renderers and the blob-origin checks, and verified the x-chat suites in jsdom and Chromium on React 18 and the current React version.

@hasdfa
hasdfa merged commit cfd7257 into mui:master Jul 21, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: chat Changes related to the AI chat. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants