Description
RubyIndexer::Configuration#indexable_uris and #top_level_directories use Dir.glob with the workspace path interpolated into the pattern:
# indexable_uris (line 71)
Dir.glob(File.join(@workspace_path, pattern), flags)
# top_level_directories (line 268)
Dir.glob("#{Dir.pwd}/*")
If @workspace_path or Dir.pwd contains [, ], {, or }, these are interpreted as glob metacharacters rather than literal path characters.
Why this wasn't fixed in #4022
The natural fix is to use Dir.glob's base: parameter, which treats the base path literally:
Dir.glob(pattern, flags, base: @workspace_path)
However, this triggers a Ruby Dir.glob bug: when top_level_directories returns an empty array (e.g., in a minimal project with no subdirectories), the included pattern becomes "{}/**/*.rb". With the base: parameter, Dir.glob("{}/**/*.rb", base: dir) incorrectly traverses outside the base directory into system paths, causing Errno::EPERM on macOS protected directories. The joined-path form Dir.glob(File.join(dir, "{}/**/*.rb")) correctly returns [].
Possible approaches
- Guard against empty
top_level_directories before constructing the pattern (avoid {} in glob)
- Use
File.join but escape glob metacharacters in the workspace path portion with backslashes
- File a Ruby bug report for the
Dir.glob base: + empty braces behavior
Impact
Low — workspace root paths rarely contain brackets or braces. This is a hardening issue rather than a user-facing bug.
Description
RubyIndexer::Configuration#indexable_urisand#top_level_directoriesuseDir.globwith the workspace path interpolated into the pattern:If
@workspace_pathorDir.pwdcontains[,],{, or}, these are interpreted as glob metacharacters rather than literal path characters.Why this wasn't fixed in #4022
The natural fix is to use
Dir.glob'sbase:parameter, which treats the base path literally:However, this triggers a Ruby
Dir.globbug: whentop_level_directoriesreturns an empty array (e.g., in a minimal project with no subdirectories), the included pattern becomes"{}/**/*.rb". With thebase:parameter,Dir.glob("{}/**/*.rb", base: dir)incorrectly traverses outside the base directory into system paths, causingErrno::EPERMon macOS protected directories. The joined-path formDir.glob(File.join(dir, "{}/**/*.rb"))correctly returns[].Possible approaches
top_level_directoriesbefore constructing the pattern (avoid{}in glob)File.joinbut escape glob metacharacters in the workspace path portion with backslashesDir.globbase:+ empty braces behaviorImpact
Low — workspace root paths rarely contain brackets or braces. This is a hardening issue rather than a user-facing bug.