From bdf15c7566b7bdbdd001e9837356ba6bb0029840 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 13 Oct 2026 15:54:15 -0400 Subject: [PATCH] Use File::path for FFI --- lib/prism/ffi.rb | 10 +++++----- test/prism/api/parse_test.rb | 8 ++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index a0948beddb..57cd6c490b 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -217,12 +217,12 @@ def self.with_string(string) # Yields a PrismSource to the given block, backed by a pm_source_t. def self.with_file(filepath, options) - unless filepath.is_a?(String) - filepath = filepath.to_path if filepath.respond_to?(:to_path) - filepath = filepath.to_str if filepath.respond_to?(:to_str) - end + # File.path applies the same coercion and validation as the C + # extension's rb_get_path: it accepts to_path/to_str objects and + # rejects paths containing a NUL byte, which would otherwise truncate + # the path when it is handed to C as a NUL-terminated string. + filepath = File.path(filepath) options[:filepath] = filepath - raise TypeError unless filepath.is_a?(String) # On Windows and Mac, it's expected that filepaths will be encoded in # UTF-8. If they are not, we need to convert them to UTF-8 before diff --git a/test/prism/api/parse_test.rb b/test/prism/api/parse_test.rb index c66a69caf9..68ffe33078 100644 --- a/test/prism/api/parse_test.rb +++ b/test/prism/api/parse_test.rb @@ -61,6 +61,14 @@ def test_parse_file end end + def test_parse_file_null_byte + Dir.mktmpdir do |dir| + path = File.join(dir, "target.txt") + File.write(path, "# secret") + assert_raise(ArgumentError) { Prism.parse_file("#{path}\0.rb") } + end + end + def test_parse_tempfile Tempfile.create(["test_parse_tempfile", ".rb"]) do |t| t.puts ["begin\n", " end\n"]