Visitar URL original
Fix non-ASCII and special-character filenames in directory mode by shirayu · Pull Request #122 · thiagokokada/gh-gfm-preview · GitHub
Skip to content

Fix non-ASCII and special-character filenames in directory mode - #122

Merged
thiagokokada merged 4 commits into
thiagokokada:mainfrom
shirayu:fix_url_for_non_ascii
Jul 24, 2026
Merged

thiagokokada merged 4 commits into
thiagokokada:mainfrom
shirayu:fix_url_for_non_ascii

Conversation

@shirayu

@shirayu shirayu commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Directory-listing mode (-D) had two bugs that broke non-ASCII and special-character filenames:

  1. Double percent-encoding in live reload (script.js)
    window.location.pathname is already percent-encoded by the browser
    (e.g. /日本語.md → /%E6%97%A5%E6%9C%AC%E8%AA%9E.md). The
    loadMarkdown() fetch wrapped it in encodeURIComponent() again,
    producing %25E3%2583%2586…. The /__/md endpoint decoded only one
    layer, looked up the literal string %E6%97%A5… on disk, and returned
    404. The correctly server-rendered page was then overwritten with
    an error message.

  2. No HTML/URL escaping in the template (text/template)
    The HTML template used text/template, which performs no contextual
    escaping. Filenames containing &, <, > could break the markup,
    and filenames containing # or non-ASCII characters produced invalid
    href attributes (e.g. href="/file#1.md" — the browser treats
    #1.md as a fragment).

Changes

internal/server/static/script.js

Decode window.location.pathname before re-encoding so the /__/md
query parameter is single-encoded:

// before
`/__/md?path=${encodeURIComponent(window.location.pathname.slice(1))}`
// after
`/__/md?path=${encodeURIComponent(decodeURIComponent(window.location.pathname.slice(1)))}`

internal/server/server.go, types.go, directory_handler.go

  • Switch text/template → html/template for automatic contextual
    HTML escaping of filenames, titles, and breadcrumb labels.
  • Add a urlPathEscape template function that percent-encodes each
    path segment (url.PathEscape) while preserving / separators.
  • Change TemplateParam.Body and HeadingsHTML to template.HTML
    so intentionally rendered Markdown HTML is not escaped.

internal/server/template.html

Use {{urlPathEscape .Path}} in all href attributes (file tree,
directory index, breadcrumbs, back-to-README link).

Tests (internal/server/nonascii_test.go, fixtures in testdata/nonascii/)

  • /__/md endpoint returns correct content for Japanese/Chinese paths.
  • Page render returns 200 for non-ASCII, &, and # filenames.
  • Directory listing HTML-escapes display names (foo&amp;bar.md).
  • Directory listing percent-encodes hrefs (%E6%97%A5…, file%231.md).
  • Rendered Markdown body is not double-escaped.
  • Breadcrumb labels render correctly.

Affected flags / modes

  • --directory-listing (-D): primary fix target.
  • Single-file mode: unaffected (no path in URL, no directory listing).
  • No flag interface changes.

Testing

GOCACHE=/tmp/go-build CGO_ENABLED=0 go test ./internal/...
./jslint.sh internal/server/static/script.js

shirayu and others added 4 commits July 24, 2026 01:54
Switch from text/template to html/template so that filenames containing
HTML-special characters (&, <, >) are automatically escaped in rendered
output, preventing broken markup.

Add a urlPathEscape template function that percent-encodes each path
segment for use in href attributes. This ensures non-ASCII characters
(e.g. Japanese, Chinese) and URL-special characters (#, &) produce
valid, clickable links in directory listings and breadcrumbs.

Fix double percent-encoding in the live-reload fetch (script.js):
window.location.pathname is already percent-encoded by the browser, so
decode it before re-encoding with encodeURIComponent. Without this fix,
the /__/md endpoint received a double-encoded path and returned 404 for
any non-ASCII filename.

Mark TemplateParam.Body and HeadingsHTML as template.HTML to preserve
intentionally raw Markdown-rendered HTML through the html/template
escaping pipeline.
@thiagokokada

This comment was marked as outdated.

@chatgpt-codex-connector

This comment was marked as low quality.

@thiagokokada

Copy link
Copy Markdown
Owner

@codex

@chatgpt-codex-connector

This comment was marked as low quality.

@thiagokokada
thiagokokada merged commit c127e30 into thiagokokada:main Jul 24, 2026
2 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 5d8d6a45d0

ℹ️ 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".

@shirayu
shirayu deleted the fix_url_for_non_ascii branch July 24, 2026 09:47
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.

2 participants