Repository navigation
fix(cli,server): handle UTF-8 file paths on Windows - #2145
Conversation
Outputs and previews were built with std::filesystem::path(std::string) and written through path::string(), std::ofstream(std::string) and stb without STBI_WINDOWS_UTF8, which all use the ANSI code page: "café.png" was written as "café.png". -r, --ref-video, --ref-video-audio, --ref-audio, --audio, --prompt-file, --negative-prompt-file and --imat-in took the raw argv, also in the ANSI code page, so they failed on characters it cannot represent. Read those options with argv_to_utf8 (now declared in common.h), define STBI_WINDOWS_UTF8 and STBIW_WINDOWS_UTF8, and build and print paths with fs::u8path and path::u8string. A LoRA name from the prompt that is not valid UTF-8 is reported and skipped instead of throwing.
|
Verified on the official master-970 release binaries (2f016e8) — this PR and companion #2144. Thank you. Datapoint (Windows 11, ANSI code page 1252, official Before (8cd731e): exit 0, the real After (2f016e8): the same command writes into the real directory, valid PNG, and the image is pixel-identical to an ASCII-output run at the same seed. Companion #2144 validated in the same run (accented model path now loads). |
…to_claude Brings in the 20 upstream commits since 2988060 (2026-10-11): per-module automatic flash attention (leejet#2132), automatic direct convolution (leejet#2134, leejet#2141), reclaim before trusting wrapped Vulkan iGPU memory estimates (leejet#2124), UTF-8 file paths on Windows (leejet#2144, leejet#2145), FP8 CPU crash fix (leejet#2140), the ggml sync to dc99877 (leejet#2147), FLUX.3 Klein, MOSS-Image, the MoSR upscaler, MiniMax-H3 LoRAs, Qwen Image 2.1 Turbo preset, ROCm and MUSA Dockerfiles, documentation. Conflicts resolved, keeping both sides: - include/stable-diffusion.h: upstream's flash_attn_mode and conv_direct_mode stay right after conditioning_cache_size, so the layout up to there is still upstream's; memory_guard, disable_backend_fallback and multi_gpu follow. - src/core/ggml_extend_backend.cpp: upstream's new cuda_compiled_arch() keeps asking the compute capability through sd::cuda_driver (the driver is looked up at run time, so the engine starts where there is no NVIDIA driver), not through <cuda.h>; the HIP include from upstream is kept. - src/model_manager.cpp: the CPU memory guard and upstream's requires_reclamation rule are both applied: a Vulkan iGPU estimate that wrapped is reclaimed before it is trusted, and the guard still decides for the CPU backend. - src/model_loader.cpp: includes of both sides; load_worker keeps the file handle pool and the open retry. - examples/server/runtime.cpp: --degradation-cooldown check and upstream's u8path for the --serve-html-path check. - docs/backend.md: the "Several GPUs" section and upstream's "Direct convolution" and "Flash attention" sections. The ggml submodule moves from d25b121 to dc99877 (upstream's pin). Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EhZzDBkuuMp1jBf4WtEySC
Companion of #2144 (the same fix in the library, for model files). The two PRs are independent and each builds on its own.
Problem
On Windows the CLI reads most options as UTF-8 (
argv_to_utf8()), but:std::filesystem::path(std::string)and written through
path::string(),std::ofstream(std::string)andstb without
STBI_WINDOWS_UTF8/STBIW_WINDOWS_UTF8, all of which use theANSI code page.
-o "D:\essai_été\café.png"logssave result image 0 to '...\essai_été\café.png' (success)but the fileis written to
...\essai_été\café.png;-r,--ref-video,--ref-video-audio,--ref-audio,--audio,--prompt-file,--negative-prompt-fileand--imat-intake the rawargv[index], which is in the ANSI code page. They work for charactersthat code page can represent and fail for the others (
-r "...\参照\写真.png"→load image from '...\??\??.png' failed). They would also disagree withevery UTF-8 path once those are fixed.
Changes
argv_to_utf8(); it is declared incommon.hso--imat-inincli/main.cppcan use it too.media_io.cppdefinesSTBI_WINDOWS_UTF8andSTBIW_WINDOWS_UTF8(stb only acts on them under
_WIN32).fs::u8path(...)and turned back into stringswith
.u8string()(output, preview, sidecar audio, video, imagedirectories, embeddings, LoRA and model directories, prompt files,
server model/LoRA/upscaler listings,
serve_html_path).file in another encoding) is reported and skipped instead of throwing.
No change on Linux/macOS.
Verification
Windows 11 (ANSI code page 1252), MSVC 14.44,
-DSD_CUDA=OFF, master8cd731e, FLUX.2 klein 4B Q4_0 (256x256, 4 steps, seed 1):
-o ...\essai_été\café.pngessai_été\café.pngessai_été\café.png-o ...\東京\画像.png東京\画像.png-r ...\参照\写真.pngload image ... '??\??.png' failed, exit 1-r ...\entrée\référence.png-o ...\plain\coffee.png🤖 Generated with Claude Code
Summary by CodeRabbit