`process.execPath` uses the ANSI API on Windows, so non-ASCII paths are garbled when the ANSI code page is not UTF-8
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- Mezza giornata
- Idoneità per principianti
- 72/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- c, typescript
- Ambito
- operating-systems
Direzione di ricerca
Inizia da scr_process_exec_path() in packages/runtime/src/scr_lib.c (intorno alla riga 761) e confrontala con scr_process_cwd() nello stesso file, che usa già l'API a caratteri wide e scr_fs_win_utf8(). La modifica consiste nel passare il ramo Windows a GetModuleFileNameW, convertire il risultato in UTF-8 e mantenere il fallback esistente su argv[0]. È completato quando un percorso di eseguibile con caratteri non ASCII viene restituito correttamente in una build Windows CP932, il che richiede una build cross come SCRIPTC_BUILD_CROSS=1 con SCRIPTC_TARGET=x86_64-windows-gnu.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
English is translated from the Japanese original below.
Checked against main at 0db50d64b (v0.4.7-578).
Summary
In executables built for Windows, process.execPath is garbled when the path contains non-ASCII characters and the ANSI code page is not UTF-8 (for example CP932, the default on Japanese Windows).
scr_process_exec_path() (packages/runtime/src/scr_lib.c, L761) reads the path with GetModuleFileNameA and stores the bytes in the system code page as UTF-8. Elsewhere in the same file, such as scr_process_cwd(), paths go through a Unicode API and scr_fs_win_utf8(). execPath is the one place that was missed.
The garbled value also reaches child processes. The Windows arm of fork() (scr_child.c, L2476) and scr_node_island.c (L184, L678) pass scr_process_exec_path() to the spawn code, which treats it as UTF-8 and converts it for CreateProcessW. On a CP932 machine, child_process.fork() from an executable in a path with Japanese characters should therefore fail to find the executable. I haven't verified the fork() failure on a real machine.
Observed
- Windows with the ANSI code page set to UTF-8: not garbled.
- Windows with CP932: garbled when the executable's path contains Japanese characters.
- An executable built with the runtime fix below returns the path correctly on a real CP932 machine. It was cross-built from Linux with
SCRIPTC_BUILD_CROSS=1and Zig 0.16.0.
Environment: SCRIPTC_TARGET=x86_64-windows-gnu
Proposed fix
Make the Windows side of scr_process_exec_path() work like scr_process_cwd(): get the path with GetModuleFileNameW and convert it with scr_fs_win_utf8(). The result is already absolute, so it skips the ANSI _fullpath call. A failure, or a path that doesn't fit in 4096 characters, falls through to the existing argv[0] fallback. This matches Node, whose uv_exepath uses GetModuleFileNameW on Windows.
The change is about 15 lines in scr_lib.c: https://github.com/vercel-labs/scriptc/compare/main...tom96da:scriptc:fix/windows-exec-path-utf8. I can open it as a pull request.
Related calls, not verified
These calls also pass an ANSI API result or input through as UTF-8. I haven't checked any of them on a real machine.
scr_lib.cL796, L802:GetEnvironmentVariableAinscr_env_get(process.envreads). The variable name is passed as ANSI too.scr_lib.cL1479:GetUserNameAinscr_os_user_name(os.userInfo().username).scr_lib.cL1546:GetTempPathAinscr_os_tmpdir(os.tmpdir()).
scr_intl.c L78 (scr_intl_exe_dir) also uses GetModuleFileNameA, but the path goes to ICU, which opens it with an ANSI API, so it is consistent and doesn't return a value to JavaScript. It may need a separate look for non-ASCII install paths.
#321 and #323 (console output mojibake) are a separate matter.
日本語(原文)
main の 0db50d64b(v0.4.7-578)で確認しました。
概要
Windows 向けの実行ファイルで、パスに非 ASCII 文字が含まれ、ANSI コードページが UTF-8 でない場合(日本語 Windows の既定 CP932 など)に、process.execPath が文字化けします。
scr_process_exec_path()(packages/runtime/src/scr_lib.c L761)が GetModuleFileNameA でパスを取得し、システムのコードページのバイト列をそのまま UTF-8 として保持しているためです。同じファイルの scr_process_cwd() などは Unicode API と scr_fs_win_utf8() を使っており、execPath だけが漏れています。
この値は子プロセスの起動にも使われます。fork() の Windows 側(scr_child.c L2476)と scr_node_island.c(L184、L678)が scr_process_exec_path() を spawn に渡し、spawn 側はそれを UTF-8 として CreateProcessW 用に変換します。そのため CP932 環境では、日本語を含むパスにある実行ファイルからの child_process.fork() が失敗するはずです。fork() の失敗は実機では確認していません。
確認結果
- ANSI コードページが UTF-8 の Windows: 化けない
- CP932 の Windows: 日本語を含むパスの実行ファイルで化ける
- 下記の修正を入れたランタイムでビルドした実行ファイルは、CP932 の実機で化けずに取得できることを確認済み(Linux から
SCRIPTC_BUILD_CROSS=1でクロスビルド、Zig 0.16.0)
環境: SCRIPTC_TARGET=x86_64-windows-gnu
修正案
scr_process_exec_path() の Windows 側を scr_process_cwd() と同じ方式にします。GetModuleFileNameW で取得し、scr_fs_win_utf8() で UTF-8 に変換します。取得したパスは既に絶対パスなので、ANSI 版の _fullpath は通しません。失敗した場合や 4096 文字に収まらない場合は、従来の argv[0] のフォールバックに進みます。Node の uv_exepath も、Windows では GetModuleFileNameW を使っています。
変更は scr_lib.c に約 15 行です: https://github.com/vercel-labs/scriptc/compare/main...tom96da:scriptc:fix/windows-exec-path-utf8 。プルリクエストとして出せます。
関連する呼び出し(未確認)
次の呼び出しも、ANSI 版 API の結果や入力を UTF-8 としてそのまま扱っています。いずれも実機では確認していません。
scr_lib.cL796、L802:scr_env_getのGetEnvironmentVariableA(process.envの読み取り)。変数名も ANSI として渡しています。scr_lib.cL1479:scr_os_user_nameのGetUserNameA(os.userInfo().username)scr_lib.cL1546:scr_os_tmpdirのGetTempPathA(os.tmpdir())
scr_intl.c L78(scr_intl_exe_dir)も GetModuleFileNameA を使っていますが、パスは ICU に渡され、ICU 側も ANSI の API で開くため一貫しており、JavaScript には値を返しません。非 ASCII のインストール先については、別に確認が必要かもしれません。
#321 / #323(コンソール出力の文字化け)は別件です。
- Lingua principale
- TypeScript
- Stelle
- 6.4k
- Fork
- 204
- Merge medio
- 7h 37m
- PR unite (30g)
- 878
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di vercel-labs/scriptc
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
vercel-labs/scriptc#2905 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
vercel-labs/scriptc#2845 ·
I maintainer di solito rispondono entro 1 giorno
-
Allow storing util.getCallSites without capturing a stackForse già presa @jlucaso1 l’ha presa 1 giorno fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
vercel-labs/scriptc#2840 ·
I maintainer di solito rispondono entro 1 giorno
-
Register shared JavaScript object globals with unmappable inferred fieldsForse già presa @jlucaso1 l’ha presa 1 giorno fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
vercel-labs/scriptc#2837 ·
I maintainer di solito rispondono entro 1 giorno
-
Hoisted TextEncoder feature probe returns false for encodeIntoForse già presa @jlucaso1 l’ha presa 1 giorno fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
vercel-labs/scriptc#2836 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di vercel-labs/scriptc
Issue simili
-
mobile-app
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
Open-Locker/Open-Locker#352 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
leanprover-community/lean4game#589 ·
I maintainer di solito rispondono entro 2 giorni
-
Add: CS Action BGApertacheck:passed streams:add
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
unocss/unocss#5421 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno