Repository navigation
Reject null bytes in File/Dir paths as CRuby does - #88
Open
jiro-by-nori[bot] wants to merge 1 commit into
Open
jiro-by-nori[bot] wants to merge 1 commit into
jiro-by-nori[bot] wants to merge 1 commit into
Conversation
A path argument containing a null byte answered false in the VFS predicates and a value in the pure path helpers. CRuby raises ArgumentError before touching the filesystem: "path name contains null byte" for a path, and "string contains null byte" for the suffix or a File.join part. Check the path in the step-1 builtins and the helpers, and record the regression case. Authored by Jiro, an autonomous agent.
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.
Summary
A
File/Dirpath argument containing a null byte is a wrong answer, not a gate. CRuby raisesArgumentErrorbefore touching the filesystem; the model answered a concrete value orfalse:The VFS step-1 builtins (
File.exist?,File.file?,File.directory?,Dir.exist?) answeredfalse, and the pure path helpers (File.basename,File.dirname,File.extname,File.join, and aFile.basenamesuffix) answered a value.File.read/File.size/File.writehappened to gate with a misleading "no such file" reason.CRuby's messages are shape-specific, so the fix uses both:
ArgumentError, "path name contains null byte";File.joinpart or aFile.basenamesuffix containing one raisesArgumentError, "string contains null byte".ruby-lean/RubyCore/Builtins/FS.leanchecks the path before any lookup (so read/size/write also answer the real error instead of a misleading gate).ruby-lean/prelude/prelude.rbchecks the four pure helpers. The generatedPrelude*.leanfiles are regenerated withmake gen.This is step-1 VFS correctness (umbrella issue #7). It is orthogonal to #85 (VFS differential corpus) and #87 (byte counts). No proof statements change;
runFS_framestill builds becausepushRootKleaves the heap unchanged.Authored by Jiro, an autonomous agent — both this code and this description.
Test plan and validation
main's model: the new regression program printedfalse\nfalse\nfalse\nfalse\n"a\\u0000b"\n"/tmp"\n""\n"/tmp/a\\u0000b/z"\n"abc"while CRuby printed twelveArgumentErrorlines.difftest/corpus/regressions/file-path-null-byte.{rb,json}. It is a genuineDISAGREEon the old model andAGREEnow (declaredfixed, observedagree→held).uv run difftest run --tier regressions --sut lean: 220 cases, 219 agree, 1 pre-existing gate, 0 failures.scripts/check-conformance.shprints CONFORMANCE OK.uv run difftest replay corpus/tier3 --sut lean: 57 agree, 13 gated, 0 disagreements.cd books && lake build: 1399 jobs, includingrunFS_frame.bash books/scripts/check-soundness.sh --proofs-only: SOUNDNESS CHECK PASSED.make gen-check: all four generated sources fresh.python3 scripts/check-not-weakened.py: CHECKS NOT WEAKENED.uv run pytestindifftest/: 158 passed; the 6 failures are the Sorbet tests, which cannot run here because the Sorbet gem is not installed (SorbetUnavailable), unrelated to this change.Validation caveat:
make check/make lintcould not run end-to-end in this environment because Bundler cannot build the pinnedjsonnative gem. The lint configuration excludesruby-lean/prelude/**/*anddifftest/corpus/**/*, so this diff has no lint surface; the affected checks above were run individually.