mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(path): path_is_url returns false for "foo:/" #19797
Problem: path_to_url() returns false for single-slash URIs ("foo:/" vs "foo://"). This is not compliant with the URI spec. https://url.spec.whatwg.org/#url-representation LSP in particular allows single-slash URIs. Solution: Relax path_to_url() to accept single-slash URIs. This is not fully compliant (only ":" is required by the spec), but it is hopefully good enough without causing false-positives in typical text files. ref https://url.spec.whatwg.org/#windows-drive-letter ref https://github.com/neovim/neovim/pull/19773 ref https://github.com/neovim/neovim/pull/19773#issuecomment-1214763769
This commit is contained in:
parent
9a100ee169
commit
a4e4609d62
@ -33,7 +33,7 @@
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/window.h"
|
||||
|
||||
#define URL_SLASH 1 // path_is_url() has found "://"
|
||||
#define URL_SLASH 1 // path_is_url() has found ":/"
|
||||
#define URL_BACKSLASH 2 // path_is_url() has found ":\\"
|
||||
|
||||
#ifdef gen_expand_wildcards
|
||||
@ -1751,12 +1751,26 @@ char_u *find_file_name_in_path(char_u *ptr, size_t len, int options, long count,
|
||||
return file_name;
|
||||
}
|
||||
|
||||
// Check if the "://" of a URL is at the pointer, return URL_SLASH.
|
||||
/// Checks for a Windows drive letter ("C:/") at the start of the path.
|
||||
///
|
||||
/// @see https://url.spec.whatwg.org/#start-with-a-windows-drive-letter
|
||||
bool path_has_drive_letter(const char *p)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
return strlen(p) >= 2
|
||||
&& ASCII_ISALPHA(p[0])
|
||||
&& (p[1] == ':' || p[1] == '|')
|
||||
&& (strlen(p) == 2 || ((p[2] == '/') | (p[2] == '\\') | (p[2] == '?') | (p[2] == '#')));
|
||||
}
|
||||
|
||||
// Check if the ":/" of a URL is at the pointer, return URL_SLASH.
|
||||
// Also check for ":\\", which MS Internet Explorer accepts, return
|
||||
// URL_BACKSLASH.
|
||||
int path_is_url(const char *p)
|
||||
{
|
||||
if (strncmp(p, "://", 3) == 0) {
|
||||
// In the spec ':' is enough to recognize a scheme
|
||||
// https://url.spec.whatwg.org/#scheme-state
|
||||
if (strncmp(p, ":/", 2) == 0) {
|
||||
return URL_SLASH;
|
||||
} else if (strncmp(p, ":\\\\", 3) == 0) {
|
||||
return URL_BACKSLASH;
|
||||
@ -1781,6 +1795,10 @@ int path_with_url(const char *fname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (path_has_drive_letter(fname)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check body: alpha or dash
|
||||
for (p = fname + 1; (isalpha(*p) || (*p == '-')); p++) {}
|
||||
|
||||
@ -1789,7 +1807,7 @@ int path_with_url(const char *fname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// "://" or ":\\" must follow
|
||||
// ":/" or ":\\" must follow
|
||||
return path_is_url(p);
|
||||
}
|
||||
|
||||
|
@ -6582,7 +6582,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u
|
||||
|
||||
/*
|
||||
* Search forward for the last char of the file name.
|
||||
* Also allow "://" when ':' is not in 'isfname'.
|
||||
* Also allow ":/" when ':' is not in 'isfname'.
|
||||
*/
|
||||
len = 0;
|
||||
while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
|
||||
|
@ -640,6 +640,10 @@ describe('path.c', function()
|
||||
eq(2, path_with_url([[test-abc:\\xyz\foo\b3]]))
|
||||
eq(0, path_with_url([[-test://xyz/foo/b4]]))
|
||||
eq(0, path_with_url([[test-://xyz/foo/b5]]))
|
||||
eq(1, path_with_url([[test-C:/xyz/foo/b5]]))
|
||||
eq(1, path_with_url([[test-custom:/xyz/foo/b5]]))
|
||||
eq(0, path_with_url([[c:/xyz/foo/b5]]))
|
||||
eq(0, path_with_url([[C:/xyz/foo/b5]]))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user