Skip to content

Fix Windows filename/path handling (reserved names, node probe, file URLs)#13622

Draft
abidlabs wants to merge 3 commits into
mainfrom
fix/issue-13443-feature-centralized-upload-validation-extension-
Draft

Fix Windows filename/path handling (reserved names, node probe, file URLs)#13622
abidlabs wants to merge 3 commits into
mainfrom
fix/issue-13443-feature-centralized-upload-validation-extension-

Conversation

@abidlabs

Copy link
Copy Markdown
Member

Description

Hardens a few related Windows path/filename issues:

  1. [Feature] Centralized Upload Validation (Extension Blacklist & Filename Security) #13443 — Prefix Windows reserved device names (CON, PRN, AUX, NUL, COM1COM9, LPT1LPT9) in strip_invalid_filename_characters so uploads like CON.txt remain valid filesystem paths on NTFS. Follows maintainer guidance to skip a global extension blacklist and keep this as a targeted sanitizer fix.
  2. INFO: Could not find files for the given pattern(s) message appears on Windows #9974 — Pass stderr=subprocess.DEVNULL when probing for node via where/which so missing Node does not leak INFO: Could not find files for the given pattern(s). on Windows.
  3. Custom component dev server broke on windows #8781 — Use pathToFileURL(...).href (and Path.as_uri() in the SSR node server) instead of "file://" + path, which produces invalid URLs for Windows drive paths.

Closes: #13443
Closes: #9974
Closes: #8781

AI Disclosure

  • I used AI to draft the implementation and PR description; all changes were self-reviewed.
  • I did not use AI

Testing and Formatting Your Code

Verification:

PYTHONPATH=client/python python -m pytest client/python/test/test_utils.py::test_strip_invalid_filename_characters -q
bash scripts/format_backend.sh
bash scripts/format_frontend.sh

Minimal demo (not committed — demo_issue_13443.py):

from gradio_client.utils import strip_invalid_filename_characters as s

for name in ["CON.txt", "PRN.jpg", "COM1", "console.log"]:
    print(name, "->", s(name))

Expected: CON.txt_CON.txt, console.log unchanged.

Made with Cursor

…nd preview

Prefix reserved DOS device names in strip_invalid_filename_characters, silence where/which node stderr, and use proper file:// URLs for Windows paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gradio-pr-bot

gradio-pr-bot commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

🪼 branch checks and previews

Name Status URL
Spaces ready! Spaces preview
Website ready! Website preview
Storybook ready! Storybook preview
🦄 Changes detected! Details

Install Gradio from this PR

pip install https://huggingface.co/buckets/gradio/pypi-previews/resolve/5a2ac73e99eb124ad219518c39aa32dbd90ecfb0/gradio-6.20.0-py3-none-any.whl

Install Gradio Python Client from this PR

pip install "gradio-client @ git+https://github.com/gradio-app/gradio@5a2ac73e99eb124ad219518c39aa32dbd90ecfb0#subdirectory=client/python"

Import Gradio JS Client from this PR via CDN

import { Client } from "https://huggingface.co/buckets/gradio/npm-previews/resolve/5a2ac73e99eb124ad219518c39aa32dbd90ecfb0/browser.js";

@gradio-pr-bot

Copy link
Copy Markdown
Collaborator

🦄 change detected

This Pull Request includes changes to the following packages.

Package Version
@gradio/preview patch
gradio patch
gradio_client patch

  • Fix Windows filename/path handling (reserved names, node probe, file URLs)

Something isn't right?

  • Maintainers can change the version label to modify the version bump.
  • If the bot has failed to detect any changes, or if this pull request needs to update multiple packages to different versions or requires a more comprehensive changelog entry, maintainers can update the changelog file directly.

@abidlabs abidlabs added the windows-tests Run backend tests on Windows on this PR (by default, applied only to the changeset release PR) label Jul 15, 2026
Babylon.js can reject after the file-level afterAll removed the listener, causing flaky js-test failures.

Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens several Windows-specific path and filename edge cases across Gradio’s Python backend, Python client utilities, and the custom component preview/build tooling to avoid invalid filesystem paths, noisy probes, and malformed file:// URLs.

Changes:

  • Sanitize Windows reserved device names in strip_invalid_filename_characters() so uploads like CON.txt don’t fail on NTFS.
  • Suppress stderr when probing for node via where/which to prevent Windows “INFO: Could not find files…” noise.
  • Generate valid file:// URLs on Windows by using pathToFileURL(...).href (JS) and Path.as_uri() (Python).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
js/preview/src/dev.ts Switch dynamic import of gradio.config.js to pathToFileURL(...).href for valid file URLs on Windows.
js/preview/src/build.ts Same pathToFileURL(...).href fix during preview build-time config import.
js/model3D/Model3D.test.ts Adjust unhandled rejection suppression message extraction; removes global listener cleanup (needs fix).
gradio/utils.py Silence stderr for where/which node probing to avoid Windows console noise.
gradio/node_server.py Use Path.as_uri() for Windows --import file URLs to avoid invalid drive-path URLs.
client/python/test/test_utils.py Add tests covering Windows reserved device name sanitization.
client/python/gradio_client/utils.py Implement reserved-device-name prefixing in strip_invalid_filename_characters().
.changeset/rude-forks-agree.md Add Changeset entry for the patch release(s).
Comments suppressed due to low confidence (1)

gradio/utils.py:1847

  • The Windows where node probe can raise FileNotFoundError if where is unavailable (e.g. non-standard Windows environments). The Unix branch already guards this; the Windows branch should catch it too to avoid crashing while probing for Node.
    try:
        # On Windows, try using 'where' command. Suppress stderr so a missing
        # node does not print "INFO: Could not find files for the given pattern(s)."
        if sys.platform == "win32":
            windows_path = (
                subprocess.check_output(["where", "node"], stderr=subprocess.DEVNULL)
                .decode()
                .strip()
                .split("\r\n")[0]
            )
            if os.path.exists(windows_path):
                return windows_path
    except subprocess.CalledProcessError:
        # Command failed, fall back to checking common install locations
        pass

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 43 to 47
beforeAll(() => {
window.addEventListener("unhandledrejection", suppress_3d_library_errors);
});

afterAll(() => {
window.removeEventListener("unhandledrejection", suppress_3d_library_errors);
});

const base_props = {
"gradio_client": patch
---

fix:Fix Windows filename/path handling (reserved names, node probe, file URLs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

windows-tests Run backend tests on Windows on this PR (by default, applied only to the changeset release PR)

Projects

None yet

3 participants