Skip to content

Fix resource paths containing hash characters#8581

Open
adamsardo wants to merge 3 commits into4ian:masterfrom
adamsardo:fix-encoded-resource-paths
Open

Fix resource paths containing hash characters#8581
adamsardo wants to merge 3 commits into4ian:masterfrom
adamsardo:fix-encoded-resource-paths

Conversation

@adamsardo
Copy link
Copy Markdown

Summary

  • Build Electron local file URLs with Node pathToFileURL, so #, spaces, and non-ASCII path characters are encoded before <img>/Pixi see them.
  • Encode local/exported runtime resource URLs before adding cache-busting or token query parameters, so # is not interpreted as a fragment in exported games or in-game preview.

Fixes #4015.

Checks

  • git diff --check
  • npx --yes prettier@1.15.3 --list-different newIDE/app/src/ResourcesLoader/index.js
  • npx --yes prettier@3.4.2 --list-different GDJS/Runtime/ResourceLoader.ts
  • Targeted Node check for Game Jam #1/Parts/hero.png -> Game%20Jam%20%231/Parts/hero.png and pathToFileURL output for local paths with #.

@adamsardo adamsardo requested a review from 4ian as a code owner May 9, 2026 11:59
@adamsardo
Copy link
Copy Markdown
Author

CI note after the first Semaphore run: the failed jobs are not pointing at the resource-loader changes in this PR.

The red Semaphore jobs fail while parsing generated libGD.js artifacts:

  • newIDE typing: ../public/libGD.js reports TypeScript syntax errors starting at line 22.
  • newIDE tests: Jest fails before running suites because libGD.js-for-tests-only has an unexpected token.

This is the same class of generated-libGD.js failure visible on the older #8393 attempt for this issue. The current diff here only touches:

  • newIDE/app/src/ResourcesLoader/index.js
  • GDJS/Runtime/ResourceLoader.ts

The broader point of this PR versus the older editor-only attempt is that it encodes local paths both where the Electron editor resolves local files and where the GDJS runtime builds resource URLs for preview/exported games. That should cover the maintainer question from #8393 about previewed projects and exported games.

Local checks still pass:

  • git diff --check
  • npx --yes prettier@1.15.3 --list-different newIDE/app/src/ResourcesLoader/index.js
  • npx --yes prettier@3.4.2 --list-different GDJS/Runtime/ResourceLoader.ts

@adamsardo
Copy link
Copy Markdown
Author

Follow-up on CI: Travis found a real test-environment gap from this PR. ResourcesLoader now optionally requires Node’s url module, but the Jest OptionalRequire mock did not support url, so three unrelated suites failed before executing.

I pushed f5c52b1 to add url to the mock. The Travis-failing suites now pass locally under Node 16:

mise x node@16 -- npm test -- --runTestsByPath src/ProjectsStorage/LocalFileStorageProvider/LocalFileResourceMover.spec.js src/ProjectsStorage/DownloadFileStorageProvider/DownloadFileSaveAsDialog.spec.js src/ResourcesList/LocalResourceExternalEditors.spec.js --watchAll=false

Also rechecked:

  • git diff --check
  • mise x node@16 -- npm run check-format

@adamsardo
Copy link
Copy Markdown
Author

Travis is now green on f5c52b1. The remaining red status is Semaphore fast tests, and its logs still fail before this PR code is exercised because generated libGD.js / libGD.js-for-tests-only cannot be parsed:

  • newIDE typing: TypeScript errors in ../public/libGD.js, starting at line 22.
  • newIDE tests: Jest fails while requiring libGD.js-for-tests-only, before test suites run.

The focused local checks for the PR change still pass under Node 16, including the suites Travis previously failed on.

@adamsardo
Copy link
Copy Markdown
Author

Added a focused regression test in d8c6678 for the original hash-path failure mode:

mise x node@16 -- npm test -- --runTestsByPath src/ResourcesLoader/index.spec.js --watchAll=false

The test asserts that a local project/resource path containing # is converted to a file:// URL with %23 before the cache query is appended, so the browser does not treat part of the filename as a fragment.

Current local validation on the latest branch:

  • targeted regression test passes
  • targeted Prettier check passes
  • targeted ESLint check passes
  • git diff --check passes

CI note: Semaphore fast tests are red again, but the public Semaphore page for the latest run does not expose detailed logs without sign-in. The earlier visible Semaphore failure on this PR was the generated libGD.js / libGD.js-for-tests-only parse failure, matching the older #8393 attempt and failing before the resource-loader code was exercised. Travis is still pending on the latest commit as of this comment.

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.

[$20.00 bounty] In a filepath a hashtag broke the preview

2 participants