Fix Windows-specific cobj.exe bugs (#828) - #862
Open
yutaro-sakamoto wants to merge 7 commits into
Open
Conversation
codegen.c kept the inside_check/inside_stack bookkeeping from the original C code generator, but only the decrements survived the rewrite to Java code generation: nothing ever increments inside_check. On non-GCC builds (the MSVC-built cobj.exe) the counter goes negative as soon as a runtime check is attached to a reference (-debug with a variable subscript, reference modification or SEARCH ALL), and inside_stack[inside_check - 1] then writes out of bounds, crashing the compiler. GCC builds never compile these blocks, which is why Linux was unaffected. Remove the machinery entirely: the generated Java must not depend on the compiler that built cobj. Un-skip the Windows tests that were failing due to this crash. Fixes opensourcecobol#829, opensourcecobol#831, opensourcecobol#832, opensourcecobol#833, opensourcecobol#834 (sub-issues of opensourcecobol#828)
With -java-package the jar arguments were assembled as package_dir + file_path_delimitor + class, mixing the '/' separators from the package path with '\' on Windows (e.g. com/abc\prog.class), which produces malformed entry names in the archive. The jar tool accepts '/' everywhere, so join the paths with '/' unconditionally. The class file cleanup after archiving had the opposite problem: cmd.exe's del does not accept '/' separators. Build the remove paths with the native separator, let cd handle the output directory, and drop a leftover '#aaa' token that del would treat as an argument. Un-skip the Windows jar test. Fixes opensourcecobol#830 (sub-issue of opensourcecobol#828)
Removing the inside_check block exposed a variableScope finding for 'code' in joutput_stmt; declare it in the handler block where it is used.
Every program in a translation unit becomes its own .java/.class file named after the program ID, so two programs whose IDs differ only in letter case overwrite each other's files on a case-insensitive filesystem and the result silently misbehaves. On Windows, detect the collision before code generation and fail with an explicit error. The two affected tests stay skipped on Windows because the behavior they exercise is impossible there by design; a new Windows-only test verifies the diagnostic instead. Fixes opensourcecobol#835 (sub-issue of opensourcecobol#828)
On case-insensitive file systems programs whose PROGRAM-IDs differ only in letter case would generate class files with the same name; cobj now reports a compile error there, so document the restriction in the usage section.
* Use "cd /d" on Windows: cmd.exe's plain "cd" does not switch drives, so with -o pointing at another drive the jar and del commands would run against the wrong directory * Replace the unbounded strcpy into package_dir_native with snprintf and give package_name_to_path an explicit output bound, so an overlong -java-package argument can no longer overflow the buffers
yutaro-sakamoto
marked this pull request as ready for review
July 26, 2026 16:29
This was referenced Aug 8, 2026
This was referenced Aug 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
#828 とその sub issue(#829〜#835)で報告された、Windows 固有の cobj.exe の不具合を修正します。
修正内容
1. MSVC ビルドでの segfault 5 件(#829, #831, #832, #833, #834)
根本原因は 1 つでした。
cobj/codegen.cに、C コードを生成していた opensource-cobol 由来のinside_check/inside_stack機構が残っており、Java コード生成への書き換え時にデクリメントだけが生き残っていました(インクリメント箇所が存在しない)。この機構は全て GCC 以外でのみコンパイルされるため、MSVC ビルドの cobj.exe だけが-debug+ 変数添字・参照変更・SEARCH ALL の組み合わせでカウンタが負になり、inside_stack[-2]への範囲外書き込みで segfault していました。生成される Java はビルドに使った C コンパイラに依存すべきではないため、機構ごと削除しました(GCC ビルドの出力・動作は不変)。2.
-java-package使用時の不正な jar パス(#830)jar コマンドの引数が「
/区切りのパッケージパス + Windows では\のfile_path_delimitor」で連結され、com/abc\prog.classのような混在パスが生成されていました。jar は全プラットフォームで/を受け付けるため/に統一。逆に cmd.exe のdelは/を受け付けないため、削除コマンドはネイティブセパレータ +cd方式に変更し、delが引数として解釈してしまう残留トークン#aaaも削除しました。3. 大文字小文字のみ異なる PROGRAM-ID(#835)
各プログラムはプログラム ID 名の .java/.class として生成されるため、大文字小文字のみ異なる ID(例:
PROGとprog)はケース非区別ファイルシステム上で互いのファイルを上書きします。これは原理的に共存不可能なため、Windows ではコード生成前に衝突を検出して明確なコンパイルエラーを報告するようにしました(従来はサイレントに壊れた成果物が生成されていました)。該当 2 テストは「FS の原理的制約」としてスキップを継続し(コメントを正確な説明に更新)、診断を検証する Windows 専用テストを新設しました。4. その他の堅牢化
cdはドライブを跨げないためcd /dを使用(-oが別ドライブを指す場合の誤動作防止)-java-packageの長い引数によるスタックバッファオーバーフローを解消(package_name_to_pathに出力サイズ引数を追加、strcpy→snprintf)検証
-debug、-jar, -single-jar and -o、SEARCH KEY IN RHS、添字範囲外 MOVE ×2、参照変更 ×3、変数参照変更 MOVE)のAT_SKIP_IFを削除し、フォークの Windows CI で全て pass#ifdef _WIN32)既知のフォローアップ候補(別 issue 相当)
_WIN32のみ対象Fixes #829
Fixes #830
Fixes #831
Fixes #832
Fixes #833
Fixes #834
Fixes #835
Part of #828
Summary
Fixes the Windows-specific cobj.exe bugs reported in #828 and its sub-issues (#829-#835).
Changes
1. Five MSVC segfaults (#829, #831, #832, #833, #834)
One root cause:
cobj/codegen.ckept theinside_check/inside_stackbookkeeping inherited from opensource-cobol's C code generator, but only the decrements survived the rewrite to Java code generation — nothing ever increments the counter. The blocks only compile on non-GCC builds, so the MSVC-built cobj.exe alone drove the counter negative whenever a runtime check was attached (-debugwith a variable subscript, reference modification, or SEARCH ALL) and wrote out of bounds viainside_stack[-2]. The machinery is removed entirely; generated Java must not depend on the compiler that built cobj, and GCC builds are unaffected.2. Malformed jar paths with
-java-package(#830)The jar arguments mixed '/' from the package path with '\' from
file_path_delimitoron Windows (e.g.com/abc\prog.class). The jar tool accepts '/' everywhere, so the paths are now joined with '/' unconditionally. The cleanup command had the opposite problem — cmd.exe'sdelrejects '/' — so it now uses native separators viacd, and a leftover#aaatoken was removed.3. PROGRAM-IDs differing only in letter case (#835)
Each program becomes its own
.java/.classnamed after the program ID, so IDs differing only in case overwrite each other's files on a case-insensitive filesystem. This cannot work by design, so on Windows cobj now detects the collision before code generation and fails with an explicit error instead of silently producing broken output. The two affected tests remain skipped on Windows with accurate comments, and a new Windows-only test verifies the diagnostic.4. Additional hardening
cd /don Windows so the jar/del commands work when-opoints at another drive-java-packagearguments (package_name_to_pathnow takes an output bound;strcpyreplaced withsnprintf)Verification
AT_SKIP_IFfrom the nine previously skipped Windows tests; all pass on the fork's Windows CI, as does the new case-collision diagnostic test#ifdef _WIN32Known follow-up candidates
_WIN32predicate