Skip to content

Fix local Markdown images with URL-encoded paths - #11

Merged
Bowlerr merged 1 commit into
mainfrom
image-fix
Jul 12, 2026
Merged

Fix local Markdown images with URL-encoded paths#11
Bowlerr merged 1 commit into
mainfrom
image-fix

Conversation

@Bowlerr

@Bowlerr Bowlerr commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • resolve URL-encoded local image path segments before converting them to webview resource URIs
  • reject encoded path separators and malformed encoding without crashing or widening resource access
  • preserve remote URLs, query strings, SVG fragments, literal percent filenames, and existing workspace containment
  • add unit and end-to-end fixtures for inline, angle-bracket, and reference-style Markdown image syntax

Root cause

Markdown image destinations such as name%20with%20spaces.png reached vscode.Uri.joinPath still URL-encoded. joinPath treats its arguments as filesystem path text, so the percent sequence became part of the filename and the extension attempted to load name%20with%20spaces.png instead of name with spaces.png.

The fix decodes each relative URI path segment exactly once at the URI-to-filesystem boundary. Encoded forward and backward slashes are rejected so decoding cannot introduce new path boundaries. Absolute file: URLs continue through vscode.Uri.parse, and workspace containment is checked against the final resolved URI.

Validation

  • npm run test:unit - 119 tests passed
  • npm run lint - passed
  • npm run build - passed
  • npm run test:e2e - 3 passed, 1 optional GUI test skipped
  • focused strict TypeScript check for linkResolver.ts - passed
  • git diff --check - passed

Type-check note

The repository-wide npx tsc --noEmit command still reports existing unrelated strict-type errors and missing third-party declarations. No error is reported in the changed production resolver.

Summary by CodeRabbit

  • New Features

    • Improved Markdown image handling for spaces, special characters, encoded paths, angle-bracket destinations and reference-style links.
    • Remote HTTP/HTTPS images remain unchanged when supported.
  • Bug Fixes

    • Prevented unsafe encoded path traversal and malformed image paths from being resolved.
    • Preserved SVG fragments and correctly handled encoded filenames.
  • Tests

    • Added comprehensive coverage for local, remote, encoded and unsafe image references.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Local image resolution now safely decodes encoded paths, rejects encoded separators, handles file URIs defensively, and adds coverage for spaces, fragments, references, remote URLs, and malformed inputs.

Changes

Local image path resolution

Layer / File(s) Summary
Safe local path decoding
src/extension/preview/markdown/linkResolver.ts
Local image paths are decoded once, encoded separators are rejected, file URI errors are contained, and workspace validation remains enforced.
URI representation and unit coverage
test/unit/helpers/vscodeMock.ts, test/unit/linkResolver.test.ts
The URI mock now encodes file paths consistently, with tests covering encoded paths, traversal, malformed input, fragments, and remote URLs.
Pipeline and end-to-end validation
test/unit/markdownPipeline.test.ts, .e2e-workspace/image-paths.md, test/e2e/preview.e2e.test.ts
Pipeline and end-to-end coverage validates inline, angle-bracket, reference-style, encoded, spaced, and remote image destinations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

A rabbit hops through paths encoded tight,
Rejecting sneaky separators from sight.
Spaces, hashes, references too,
Pass safely through the preview queue.
“Thump!” says Bun, “the tests all shine!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing local Markdown image resolution for URL-encoded paths.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch image-fix

Comment @coderabbitai help to get the list of available commands.

@Bowlerr Bowlerr linked an issue Jul 12, 2026 that may be closed by this pull request
@Bowlerr

Bowlerr commented Jul 12, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
test/e2e/preview.e2e.test.ts (1)

54-57: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Exercise these cases through the preview UI.

These assertions only validate fixture contents; they do not open image-paths.md or verify rendered image resource URIs. A parser-to-preview integration regression would still pass. Add preview-level assertions for the three local image forms.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/preview.e2e.test.ts` around lines 54 - 57, Extend the preview UI
flow in the image-paths end-to-end test to open image-paths.md and assert
rendered image resource URIs for the three local image forms: normal paths,
percent-encoded spaces, and angle-bracket paths with spaces. Keep the existing
fixture-content assertions, but add preview-level checks that verify each
corresponding image is actually rendered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/e2e/preview.e2e.test.ts`:
- Around line 54-57: Extend the preview UI flow in the image-paths end-to-end
test to open image-paths.md and assert rendered image resource URIs for the
three local image forms: normal paths, percent-encoded spaces, and angle-bracket
paths with spaces. Keep the existing fixture-content assertions, but add
preview-level checks that verify each corresponding image is actually rendered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 35352d69-9489-4f19-a592-3574d3b15685

📥 Commits

Reviewing files that changed from the base of the PR and between 19d31c5 and 625df90.

⛔ Files ignored due to path filters (2)
  • .e2e-workspace/assets/name with spaces.svg is excluded by !**/*.svg
  • .e2e-workspace/assets/normal-image.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • .e2e-workspace/image-paths.md
  • src/extension/preview/markdown/linkResolver.ts
  • test/e2e/preview.e2e.test.ts
  • test/unit/helpers/vscodeMock.ts
  • test/unit/linkResolver.test.ts
  • test/unit/markdownPipeline.test.ts

@Bowlerr
Bowlerr marked this pull request as ready for review July 12, 2026 14:33
@Bowlerr
Bowlerr merged commit 0b483c2 into main Jul 12, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

image rendering breaks if image name contains spaces

1 participant