Compare commits

..

1 Commits

Author SHA1 Message Date
Shawn Yuan
1a145fd136 Fix peek issue (#44456)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This pull request focuses on improving the security and behavior of
Markdown file previews. The main changes include disabling HTML
rendering in Markdown to prevent potential security issues, and ensuring
that the `IsDevFilePreview` flag is set correctly when previewing
Markdown files.

**Markdown rendering and preview behavior:**

* Disabled HTML rendering in the Markdown pipeline by adding
`.DisableHtml()` in `MarkdownHelper.MarkdownHtml`, which helps prevent
XSS and other security issues in file previews.
* Explicitly set `IsDevFilePreview` to `false` when handling Markdown
files in `WebBrowserPreviewer`, ensuring correct preview state.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-12-29 14:23:16 +08:00
3 changed files with 20 additions and 32 deletions

View File

@@ -39,7 +39,7 @@ namespace Microsoft.PowerToys.FilePreviewCommon
var softlineBreak = new Markdig.Extensions.Hardlines.SoftlineBreakAsHardlineExtension();
MarkdownPipelineBuilder pipelineBuilder;
pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley().UseYamlFrontMatter().UseMathematics();
pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley().UseYamlFrontMatter().UseMathematics().DisableHtml();
pipelineBuilder.Extensions.Add(extension);
pipelineBuilder.Extensions.Add(softlineBreak);

View File

@@ -54,8 +54,6 @@ namespace Peek.FilePreviewer.Previewers
private bool IsPng() => Item.Extension == ".png";
private bool IsSvg() => Item.Extension == ".svg";
private bool IsQoi() => Item.Extension == ".qoi";
private DispatcherQueue Dispatcher { get; }
@@ -63,7 +61,7 @@ namespace Peek.FilePreviewer.Previewers
private static readonly HashSet<string> _supportedFileTypes =
BitmapDecoder.GetDecoderInformationEnumerator()
.SelectMany(di => di.FileExtensions)
.Union([".svg", ".qoi"])
.Union([".qoi"])
.ToHashSet(StringComparer.OrdinalIgnoreCase);
public static bool IsItemSupported(IFileSystemItem item)
@@ -75,15 +73,7 @@ namespace Peek.FilePreviewer.Previewers
{
cancellationToken.ThrowIfCancellationRequested();
if (IsSvg())
{
var size = await Task.Run(Item.GetSvgSize);
if (size != null)
{
ImageSize = size.Value;
}
}
else if (IsQoi())
if (IsQoi())
{
var size = await Task.Run(Item.GetQoiSize);
if (size != null)
@@ -176,31 +166,16 @@ namespace Peek.FilePreviewer.Previewers
{
cancellationToken.ThrowIfCancellationRequested();
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
if (IsSvg())
{
var source = new SvgImageSource();
source.RasterizePixelHeight = ImageSize?.Height ?? 0;
source.RasterizePixelWidth = ImageSize?.Width ?? 0;
var loadStatus = await source.SetSourceAsync(stream.AsRandomAccessStream());
if (loadStatus != SvgImageSourceLoadStatus.Success)
{
Logger.LogError("Error loading SVG: " + loadStatus.ToString());
throw new ImageLoadingException(nameof(source));
}
Preview = source;
}
else if (IsQoi())
if (IsQoi())
{
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
using var bitmap = QoiImage.FromStream(stream);
Preview = await BitmapHelper.BitmapToImageSource(bitmap, true, cancellationToken);
}
else
{
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
Preview = new BitmapImage();
await ((BitmapImage)Preview).SetSourceAsync(stream.AsRandomAccessStream());
}

View File

@@ -33,6 +33,10 @@ namespace Peek.FilePreviewer.Previewers
// Markdown
".md",
// SVG - using WebView2 for better compatibility with complex SVGs
// (e.g., from Adobe Illustrator, Inkscape)
".svg",
};
[ObservableProperty]
@@ -111,9 +115,10 @@ namespace Peek.FilePreviewer.Previewers
{
bool isHtml = File.Extension == ".html" || File.Extension == ".htm";
bool isMarkdown = File.Extension == ".md";
bool isSvg = File.Extension == ".svg";
bool supportedByMonaco = MonacoHelper.SupportedMonacoFileTypes.Contains(File.Extension);
bool useMonaco = supportedByMonaco && !isHtml && !isMarkdown;
bool useMonaco = supportedByMonaco && !isHtml && !isMarkdown && !isSvg;
IsDevFilePreview = supportedByMonaco;
CustomContextMenu = useMonaco;
@@ -125,9 +130,17 @@ namespace Peek.FilePreviewer.Previewers
}
else if (isMarkdown)
{
IsDevFilePreview = false;
var raw = await ReadHelper.Read(File.Path.ToString());
Preview = new Uri(MarkdownHelper.PreviewTempFile(raw, File.Path, TempFolderPath.Path));
}
else if (isSvg)
{
// SVG files are rendered directly by WebView2 for better compatibility
// with complex SVGs from Adobe Illustrator, Inkscape, etc.
IsDevFilePreview = false;
Preview = new Uri(File.Path);
}
else
{
// Simple html file to preview. Shouldn't do things like enabling scripts or using a virtual mapped directory.