Repository: neovim/neovim
File: runtime/lua/vim/loader.lua (Lua)

Code before:

--- @type table<string, uv.fs_stat.result>?
local fs_stat_cache

--- @type table<string, table<string,vim.loader.ModuleInfo>>
local indexed = {}

--- @param path string
--- @return uv.fs_stat.result?
local function fs_stat_cached(path)
  if not fs_stat_cache then
    return (uv.fs_stat(path))
  end

  if not fs_stat_cache[path] then
    -- Note we must never save a stat for a non-existent path.
    -- For non-existent paths fs_stat() will return nil.
    fs_stat_cache[path] = uv.fs_stat(path)
  end
  return fs_stat_cache[path]
end

local function normalize(path)
  path = fs.normalize(path, { expand_env = false, _fast = true })

  if os.getenv('APPIMAGE') ~= nil then
    -- Avoid cache pollution caused by AppImage randomizing the program root. #31165
    -- "/tmp/.mount_nvimAmpHPH/usr/share/nvim/runtime" => "/usr/share/nvim/runtime"
    path = path:match('(/usr/.*)') or path
  end

  return path
end

local rtp_cached = {} --- @type string[]
local rtp_cache_key --- @type  string?

--- Gets the rtp excluding after directories.
--- The result is cached, and will be updated if the runtime path changes.
--- When called from a fast event, the cached value will be returned.
--- @return string[] rtp, boolean updated
local function get_rtp()
  if vim.in_fast_event() then
    return (rtp_cached or {}), false
  end
  local updated = false
  local key = vim.go.rtp
  if key ~= rtp_cache_key then
    rtp_cached = {}
    for _, path in ipairs(vim.api.nvim_get_runtime_file('', true)) do
      path = normalize(path)

Review comment (security):
since loader is very perf-sensitive, let's cache this in a `local is_appimage` near the top of the module (line 10).

Code after:
local stats = { find = { total = 0, time = 0, not_found = 0 } }

--- @type table<string, uv.fs_stat.result>?
local fs_stat_cache

--- @type table<string, table<string,vim.loader.ModuleInfo>>
local indexed = {}

--- @param path string
--- @return uv.fs_stat.result?
local function fs_stat_cached(path)
  if not fs_stat_cache then
    return (uv.fs_stat(path))
  end

  if not fs_stat_cache[path] then
    -- Note we must never save a stat for a non-existent path.
    -- For non-existent paths fs_stat() will return nil.
    fs_stat_cache[path] = uv.fs_stat(path)
  end
  return fs_stat_cache[path]
end

local function normalize(path)
  path = fs.normalize(path, { expand_env = false, _fast = true })

  if is_appimage then
    -- Avoid cache pollution caused by AppImage randomizing the program root. #31165
    -- "/tmp/.mount_nvimAmpHPH/usr/share/nvim/runtime" => "/usr/share/nvim/runtime"
    path = path:match('(/usr/.*)') or path
  end

  return path
end

local rtp_cached = {} --- @type string[]
local rtp_cache_key --- @type  string?

--- Gets the rtp excluding after directories.
--- The result is cached, and will be updated if the runtime path changes.
--- When called from a fast event, the cached value will be returned.
--- @return string[] rtp, boolean updated
local function get_rtp()
  if vim.in_fast_event() then
    return (rtp_cached or {}), false
  end
  local updated = false
  local key = vim.go.rtp
  if key ~= rtp_cache_key then
    rtp_cached = {}
    for _, path in ipairs(vim.api.nvim_get_runtime_file('', true)) do