[Windows] Fix FilePicker Returns wrong ContentType for *.webp files - #31913
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a bug in the Windows implementation of FilePicker where incorrect ContentType values were returned for various file formats, particularly .webp files which were incorrectly reported as "application/octet-stream" instead of "image/webp".
- Adds comprehensive extension-to-MIME type mapping dictionary as fallback when Windows StorageFile.ContentType API returns generic or incorrect values
- Implements smart fallback logic that preserves Windows' native ContentType when correct but uses the mapping for problematic cases
- Includes support for compound extensions like .tar.gz and handles case-insensitive matching with whitespace trimming
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Essentials/src/FileSystem/FileSystem.uwp.cs | Core implementation with MIME type mapping dictionary and fallback logic in FileBase constructor |
| src/Essentials/test/DeviceTests/Tests/FileSystem_Tests.cs | New Windows-specific test cases validating correct ContentType detection for various file extensions |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please resolve conflicts?
f2ede30 to
970c082
Compare
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 31913Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 31913" |
@kubaflo , I have resolved the conflicts |
|
/review -b feature/refactor-copilot-yml -p windows |
|
/review -b feature/refactor-copilot-yml |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
@kubaflo , Based on AI suggestion, I have modified the fix |
…d newlines + unescaped pipes) (dotnet#36031) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Problem The `[Release Readiness]` tracker issues render markdown tables built from upstream-controlled content — issue/PR **titles** dropped into pipe-delimited rows (`| #link | <title> | <…> |`). Several kinds of malformed (or hostile) title corrupt those rows: 1. **Embedded newlines.** Some `ci-scan` issues have a title containing a **literal newline** — observed live on issue dotnet#35957, whose real GitHub title spans two physical lines and ends with `(maui-pr-uitest\n[Content truncated due to length]`. An embedded `\r\n` splits the row across two physical lines, so the title tail + trailing cells land on a line that no longer contains the issue link. This was visible on the live trackers: **net10-sr9 dotnet#35867** (2 broken rows) and **net11-preview6 dotnet#35866** (3 broken rows). 2. **Unescaped pipes.** A literal `|` in a title (common — e.g. `Fix A | B`) injects an extra column. The preview engine already escaped pipes everywhere via its shared `Format-MarkdownCell`, but on the **SR** side cells were escaped ad-hoc — several embedded titles with **no newline collapse at all**. 3. **Escape-the-escaper pipe breakout.** A title may legally contain a literal `\|` (backslash immediately followed by a pipe). Escaping only the pipe turns that into `\\|`, which GitHub-flavored Markdown renders as a literal `\` followed by an **active** column delimiter — so the row still breaks out. Both engines had this latent bug. 4. **Raw `<`/`>` (HTML injection / display loss) on the SR side.** SR dropped titles in raw, so a title like `Crash <!--` could inject an HTML-comment opener, and a legitimate `List<T>` (or engine-authored placeholder text like `Bump <PatchVersion> …`) was silently swallowed by GitHub as an unknown HTML tag and never displayed. The ultimate root cause of (1) is upstream (the CI Failure Scanner producing a multi-line title), but a readiness engine should defensively sanitize any external content it embeds into its own tables. ### Fix - **`Get-ReleaseReadiness.ps1`** — introduce a single null-safe **`Format-MarkdownTableCell`** helper and route **every** SR site that embeds upstream-controlled text through it. This covers the ci-scan rows, the **Open PRs Targeting `<srBranch>`**, **regression classification**, **🔴 Blocking summary**, **🧹 Cleanup**, **📥 Open Fix PRs Inbound**, and **Ship-readiness checks** tables, **plus the candidate-PR bulleted list**. The helper: - collapses `[\r\n]+` → space (hazard 1), - escapes each `|` → `\|` and **doubles only the backslash run immediately preceding that pipe** (via a single `(\\*)\|` regex pass), so a pre-existing `\|` becomes `\\\|` (renders a literal `\|`, no breakout — hazards 2 & 3). The doubling is **scoped to pipe-adjacent runs** rather than every backslash, so a title's other backslash escapes (`\[link\](url)`, `\*not emphasis\*`) are preserved verbatim and not de-escaped into active Markdown. No-pipe-adjacent-backslash titles are unchanged (`a | b` → `a \| b`). - escapes `<`/`>` → `<`/`>` (hazard 4), **matching the preview engine** for SR↔Preview parity. - **`Get-PreviewReadiness.ps1` (`Format-MarkdownCell`)** — the newline collapse plus the same **pipe-adjacent** backslash handling so the preview engine is immune to the `\|` breakout too. **On `<`/`>` escaping (now consistent across both engines):** escaping angle brackets to entities has **zero visual cost** — `<T>` renders as `<T>` — so `List<T>` fidelity is preserved while raw HTML injection is neutralized (`<!--` → `<!--`). It also fixes a latent display bug: engine-authored `NextAction` text such as `Bump <PatchVersion> in eng/Versions.props` was previously rendered raw and **swallowed by GitHub as an unknown HTML tag**, so the Release Captain saw `Bump in eng/Versions.props`; it now displays correctly. SR is additionally hash-freeze-immune (it emits its own hash at the **top** of the body, extracted with `head -n1`) and its human-notes markers are matched **full-line-anchored**, so escaping `<>` is defense-in-depth layered on top of those backend invariants rather than the sole protection. (`.Trim()` only touches leading/trailing whitespace.) ### Tests Deterministic, offline assertions: - **`Format-MarkdownTableCell` / `Format-MarkdownCell` unit tests** — pipe escaping, LF/CRLF-run collapse, newline+pipe together, null/empty → empty string, whitespace trim; **angle brackets escaped to `<`/`>` (both engines, parity)**; **literal `\|` does NOT break out** (→ `A \\\| B`); **non-pipe backslash preserved** (`C:\dir` unchanged) and **author-escaped non-pipe Markdown not de-escaped** (`\[link\](url)` unchanged) for both engines; **`<!--` opener neutralized** to `<!--`. - **SR ci-scan row** — an embedded-newline title renders as a **single** physical row with its tail + age intact. - **SR tables (end-to-end `Format-MarkdownReport`)** — a piped+newline title in the **Open PRs Targeting**, **regression classification**, **🔴 Blocking summary**, **📥 Open Fix PRs Inbound**, and **Ship-readiness checks** tables each stays on one physical row, pipe escaped, trailing column intact; the BLOCKED ship-check next-action with `<PatchVersion>` renders entity-escaped (so GitHub actually displays it). - **Human-notes marker-forgery regressions (security)** — a title embedding `…\n<!-- …:human-notes:begin -->\n…` in a **table cell** and in the **candidate-PR list** must leave **exactly one** anchored begin-marker in the rendered body (the legitimate one), proving a hostile title cannot forge a second notes region. - **Preview engine** — `Format-MarkdownCell` collapses LF/CRLF runs and preserves the existing pipe / angle-bracket escaping contract. The discriminating assertions were verified **red on the pre-fix scripts** and **green after** (and the surgical-scoping assertions were verified red against the earlier global-doubling commit). Offline suite: **566 passed / 0 failed**; full E2E: **632 / 0**. ### Scope / follow-ups (intentionally out of this PR) - Backtick (inline-code) is intentionally **not** escaped: doing so would degrade the very common legitimate case of code-quoted titles like `` `CollectionView` ``, and an unescaped backtick is a cosmetic-only, non-structural concern (it cannot create a new column, inject HTML, or forge a human-notes marker, all of which require `|`/`<`, which **are** escaped). - Null-safety of `.title.Length` under `Set-StrictMode -Version Latest` is **pre-existing** (titles are non-null by GitHub API contract) and intentionally deferred to a focused follow-up rather than mixed into this rendering PR. - The SR "Reverts" table's "Reverts commit" column shows `?` for every row (the `This reverts commit <sha>` body-regex never resolves). Pre-existing and unrelated; noted for a future pass. - Filing an upstream issue against the CI Failure Scanner for the malformed (multi-line) titles is worth doing separately so the trackers receive clean input at the source. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…und guard) (dotnet#35955) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Problem The `/review rerun` scanner never dispatched a single AzDO run in production. Investigation across recent scheduled runs showed the agent correctly deciding `decision=trigger` for open PRs, yet **every** dispatch was aborted. Two independent bugs were responsible: 1. **Only one decision per run was ever processed.** gh-aw custom safe-output jobs run exactly once per scan. The agent was instructed to call the `trigger_rerun_review` tool once *per candidate*, so every call after the first was silently dropped by gh-aw's "max 1 item" enforcement. Even when several PRs were eligible, at most one reached the dispatch script. 2. **A false "PR not found" guard cancelled dispatches for open PRs.** `Test-GhApiPrNotFound` classified any gh error text containing "Not Found"/"Gone" (e.g. transient proxy/auth bodies) as a deleted PR, so the script logged `PR #N no longer exists; skipping stale decision` and bailed — for PRs that are demonstrably open. ### Fix 1. **Batch all decisions into one tool call.** The agent now calls `trigger_rerun_review` **exactly once per run**, passing a single `decisions` JSON array with one object per candidate PR. `Get-AgentItems` expands the array (`Expand-RerunDecisionItems`) into individual decisions, with back-compat for the legacy scalar shape. This processes *all* eligible PRs in a scan instead of just one. > Note: gh-aw v0.77.5 does **not** support `max: N` on a custom `safe-outputs.jobs.<name>`, so batching into one array-typed input is the only way to lift the one-per-run cap. 2. **Harden the not-found guard.** `Test-GhApiPrNotFound` now requires an explicit `HTTP 404`/`410` status. The fetch block logs the raw gh error and performs a second confirmation probe before skipping — it fails loud (throws) rather than silently cancelling a dispatch when the cause is ambiguous. ### Tests - 32 Pester tests pass (`Invoke-RerunReviewTrigger.Tests.ps1`), including: - 5 new tests for batched `decisions` parsing (JSON string array, object array, multi-item aggregation, legacy scalar pass-through, empty/null payloads). - A regression test ensuring bare "Not Found"/"Gone" text without an HTTP 404/410 status is **not** misclassified. - `gh aw compile rerun-review-scanner` succeeds (0 errors/warnings); the regenerated `.lock.yml` is committed and embeds the new `decisions` tool schema. ### Files - `.github/scripts/Invoke-RerunReviewTrigger.ps1` — batched decision expansion + hardened guard + raw-error logging/re-probe. - `.github/scripts/Invoke-RerunReviewTrigger.Tests.ps1` — new coverage. - `.github/workflows/rerun-review-scanner.md` — single batched `decisions` tool schema + updated agent prompt. - `.github/workflows/rerun-review-scanner.lock.yml` — recompiled. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ts (dotnet#36061) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Summary The SR release-readiness tracker overcounts the regressions header when **exactly one** regression candidate exists. The live `.NET 10 SR9` tracker ([dotnet#35867](dotnet#35867)) renders: ``` ## Regression Candidates — 13 issues scanned ``` …even though only **one** issue ([dotnet#35615](dotnet#35615)) was actually scanned. The summary table, tiers, and verdict all correctly show 1 — only the header is wrong. ### Root cause The header is built from `$regs.Count`: ```powershell $regs = $Data['regressions'] ... "## Regression Candidates — $($regs.Count) issues scanned" ``` Regression results are **hashtables**. `Get-RegressionCandidates` returns its `$results` accumulator, and when exactly one candidate matches, PowerShell **unwraps the single-element array on return**, so `$Data['regressions']` arrives as a lone hashtable rather than a 1-element array. `.Count` on a hashtable returns its **key count** (13 — `createdAt, confidence, milestone, state, closedAt, evidence, candidateFixPrs, labels, stateReason, classification, recommendedAction, issue, title`), not 1. - **N = 0** → `@()` → `.Count` = 0 ✅ (already correct) - **N = 1** → scalar hashtable → `.Count` = 13 ❌ (this bug) - **N ≥ 2** → real array → `.Count` = element count ✅ (already correct) ### Fix Force array context so `.Count` always reflects the candidate count: ```powershell $regs = @($Data['regressions']) ``` One line. The sibling SR headers (`$blockingItems`, `$cleanupItems`, `$openFixRows` are all `List[hashtable]`) and the preview engine (`Get-PreviewReadiness.ps1`, which uses `List`/`@()`-wrapped collections) are **not** affected — this is the only header fed the raw `regressions` value. ### Tests Added a **discriminating** regression test in `Test-ReleaseReadiness.ps1` that reproduces the production unwrap by assigning the regression result as a **scalar hashtable** (not `@(...)`, which would mask the bug) and asserts the header reports `1 issues scanned`, plus an N=2 guard for the already-correct path. A precondition assertion locks in that the value is a scalar hashtable so a future edit can't silently neuter the test. - ✅ Verified the new test **fails pre-fix** (renders the key count) and **passes post-fix**. - ✅ Offline suite: **569 passed / 0 failed**. - ℹ️ Full E2E: 627 passed / 3 failed — the 3 failures are **pre-existing** (live-`gh` E2E tests: `sr-source-prs.txt`, candidate JSON, `-InheritFromPriorSr` validation), reproduced identically on pristine `main` (624/3) and unrelated to this change. They pass in CI's `release-readiness.yml` Validate job, which has a proper `gh` token. ### Scope Separate, focused follow-up off `main` — unrelated to the table-escaping fix in dotnet#36031 (already merged). No behavior change beyond the header count. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updated [Magick.NET-Q8-AnyCPU](https://github.com/dlemstra/Magick.NET) from 14.12.0 to 14.13.1. <details> <summary>Release notes</summary> _Sourced from [Magick.NET-Q8-AnyCPU's releases](https://github.com/dlemstra/Magick.NET/releases)._ ## 14.13.1 ### What's Changed - Fixed loading of animated AVIF image as MagickImageCollection (#2000) - Fixed determining the number of frames when reading animated AVIF images (#2005) - Fixed loaded of indexed color PSD file (#2007) - Another fix when reading JPEG compressed TIFF files. (#2016) ### Related changes in ImageMagick since the last release of Magick.NET: - Stack overflow in fx operation (GHSA-rcr6-g7jc-f57g) - Heap Buffer Over-Write of a single byte in the JP2 encoder (GHSA-533m-3wf6-c33v) - Use-After-Free in MSL decoder (GHSA-5r4x-w6p5-222q) - Infinite Loop in the MIFF decoder can lead to CPU exhaustion (GHSA-7gg8-qqx7-92g5) - Heap Buffer Over-Write in IPL decoder when reading multiple images of different dimensions (GHSA-36wm-hprc-mcf5) - Heap Buffer Over-Write in MIFF encoder when using LZMA compression (GHSA-jcqp-6r6f-3mfx) ### Library updates: - ImageMagick 7.1.2-23 (2026-05-17) - aom 3.14.0 (2026-05-12) - openexr 3.4.11 (2026-04-30) - libhwy 1.4.0 (2026-04-23) - lcms 2.19.1 (2026-05-06) - openjph 0.27.3 (2026-05-14) **Full Changelog**: dlemstra/Magick.NET@14.13.0...14.13.1 ## 14.13.0 ### What's Changed - Added `PixelDifferenceCount` to `ErrorMetric`. ### Related changes in ImageMagick since the last release of Magick.NET: - Corrected the patch that was made earlier to fix reading JPEG compressed TIFF images (#1993) - Call CloseBlob on the correct image to prevent the blob from remaining open (#1997) ### Library updates: - ImageMagick 7.1.2-21 (2026-04-21) - harfbuzz 14.2.0 (2026-04-20) - libpng 1.6.58 (2026-04-15) - libraqm 0.10.5 (2026-04-11) - libraw 0.22.1 (2026-04-06) - libxml2 2.15.3 (2026-04-15) - openexr 3.4.9 (2026-04-17) - openjph 0.27.0 (2026-04-14) **Full Changelog**: dlemstra/Magick.NET@14.12.0...14.13.0 Commits viewable in [compare view](dlemstra/Magick.NET@14.12.0...14.13.1). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/dotnet/maui/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
448e1a0 to
8da6bcb
Compare
|
@kubaflo , The AI suggestion mentioned that an ENV ERROR occurs both with and without the fix. However, the test passed locally, attached a screenshot for reference. |
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…31913) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values. <!-- Enter description of the fix in this section --> Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values. <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #31808 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [x] Windows - [x] Mac | Before | After | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/767358b1-4129-4be8-9817-8dcc83868e0b" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/71d47ced-2c26-4fdd-b6e1-d2e2c24f3157" width="600" height="300"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>

Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
On Windows, the StorageFile.ContentType API often returns a generic or incorrect MIME type (e.g., .webp → application/octet-stream), causing FilePicker to report wrong or empty ContentType values.
Description of Change
Fixed by adding an extension-to-MIME mapping dictionary in FileSystem.uwp.cs that includes .webp and other formats. The solution uses fallback logic - it preserves Windows' native ContentType when correct, but automatically uses our mapping when Windows returns the generic "application/octet-stream" or empty values.
Issues Fixed
Fixes #31808
Tested the behavior in the following platforms.
Output Screenshot
Before-fix.mp4
After-fix.mp4