Skip to content

Commit fac5c46

Browse files
committed
Use realpaths in Cache @path_obj
If gems are loaded from symlinked directory, $LOAD_PATH has mixed symlinked and real paths, while subsequent `require`s are resolved to real path, so we can end up in situation when we rerequire the same gem with different path, `require` loads this gem again and things go BOOM. ``` From: /…/src/bootsnap/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb @ line 18 Kernel#require: 15: def require(path) 16: if resolved = Bootsnap::LoadPathCache.load_path_cache.find(path) 17: binding.pry if path == 'set' => 18: require_without_cache(resolved) 19: else 20: raise Bootsnap::LoadPathCache::CoreExt.make_load_error(path) 21: end 22: rescue Bootsnap::LoadPathCache::ReturnFalse 23: return false 24: rescue Bootsnap::LoadPathCache::FallbackScan 25: require_without_cache(path) 26: end [1] pry(main)> path => "set" [2] pry(main)> Set.new.method(:to_s).source_location => ["/real_path/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/set.rb", 629] [3] pry(main)> resolved => "/symlinked_path/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/set.rb" [4] pry(main)> require_without_cache(resolved) /symlinked_path/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/set.rb:625: warning: already initialized constant Set::InspectKey /real_path/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/set.rb:625: warning: previous definition of InspectKey was here => true [5] pry(main)> Set.new.method(:to_s).source_location => ["/symlinked_path/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/set.rb", 629] [6] pry(main)> ```
1 parent 09c9235 commit fac5c46

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

lib/bootsnap/load_path_cache/cache.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def initialize(store, path_obj, development_mode: false)
99
@development_mode = development_mode
1010
@store = store
1111
@mutex = defined?(::Mutex) ? ::Mutex.new : ::Thread::Mutex.new # TODO: Remove once Ruby 2.2 support is dropped.
12-
@path_obj = path_obj
12+
@path_obj = path_obj.map { |f| File.exist?(f) ? File.realpath(f) : f }
1313
@has_relative_paths = nil
1414
reinitialize
1515
end

0 commit comments

Comments
 (0)