1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
local M = {}
function M.get_path_type(path)
if path:sub(1, 1) == '/' then
return 'absolute'
elseif path:sub(1, 1) == '~' then
return 'home'
else
return 'relative'
end
end
function M.resolve_relative(path, base)
local result
if vim.startswith(path, './') then
result = vim.fs.joinpath(base, path:sub(3))
elseif vim.startswith(path, '../') then
local current_base = base
local remaining = path
while vim.startswith(remaining, '../') do
current_base = vim.fs.dirname(current_base)
remaining = remaining:sub(4)
end
result = vim.fs.joinpath(current_base, remaining)
else
result = vim.fs.joinpath(base, path)
end
return vim.fs.normalize(result)
end
function M.resolve(filepath, current_file)
local path_type = M.get_path_type(filepath)
if path_type == 'absolute' then
return vim.fs.normalize(filepath)
elseif path_type == 'home' then
return vim.fs.normalize(filepath)
else
local base = current_file and vim.fs.dirname(current_file)
or vim.fs.dirname(vim.api.nvim_buf_get_name(0))
return M.resolve_relative(filepath, base)
end
end
function M.strip_file_protocol(url)
return url:gsub('^file://', '')
end
function M.is_within_wiki(filepath, wiki_root)
local real_path = vim.fn.resolve(filepath)
local real_root = vim.fn.resolve(wiki_root)
local normalized_path = vim.fs.normalize(real_path)
local normalized_root = vim.fs.normalize(real_root)
return vim.startswith(normalized_path, normalized_root)
end
function M.validate_within_wiki(resolved_path, wiki_root, original_path)
if not M.is_within_wiki(resolved_path, wiki_root) then
vim.notify(
string.format('Warning: Resolved path outside wiki root: %s', original_path),
vim.log.levels.WARN
)
end
return resolved_path
end
local ALLOWED_SCHEMES = {
http = true,
https = true,
file = true,
}
function M.validate_url_scheme(url)
local scheme = url:match('^([a-zA-Z]+)://')
if scheme and not ALLOWED_SCHEMES[scheme:lower()] then
return false, string.format('URL scheme not allowed: %s', scheme)
end
return true, nil
end
return M
|