1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Special treatment for file:// URIs on Windows

* lisp/url/url-parse.el (url-generic-parse-url): Remove prefix /
when a file URI's filename starts with a single letter followed
by a colon and a slash or backslash.
(url-recreate-url): Mirror the change applied when parsing, so
the URL is recreated properly on MS-Windows.
* test/lisp/url/url-parse-tests.el
(url-generic-parse-url/ms-windows-file-uri-hanlding): New test.
(Bug#76982)
This commit is contained in:
Sebastián Monía 2025-04-08 18:09:06 -04:00 committed by Eli Zaretskii
parent 6f494d74f6
commit fec6e16f14
2 changed files with 34 additions and 1 deletions

View file

@ -83,7 +83,12 @@ If the specified port number is the default, return nil."
;; port is empty or if its value would be the same as that of
;; the scheme's default."
(port (url-port-if-non-default urlobj))
(file (url-filename urlobj))
;; For Windows/DOS-like paths, `url-generic-parse-url' strips
;; the leading /, so we need to add it back (bug#76982)
(file (if (and (string= "file" type)
(string-match "^[A-Za-z]:[/\\]" (url-filename urlobj)))
(concat "/" (url-filename urlobj))
(url-filename urlobj)))
(frag (url-target urlobj)))
(concat (if type (concat type ":"))
(if (url-fullness urlobj) "//")
@ -190,6 +195,12 @@ parses to
;; authority) at the beginning of the absolute path.
(setq save-pos (point))
;; For file:// URIs, if the path "looks like" Windows/DOS,
;; it makes sense to strip the leading slash (bug#76982)
(when (and (string= "file" scheme)
(looking-at "/[A-Za-z]:[/\\]"))
(forward-char)
(setq save-pos (point)))
(if (string= "data" scheme)
;; For the "data" URI scheme, all the rest is the FILE.
(setq file (buffer-substring save-pos (point-max)))
@ -210,6 +221,7 @@ parses to
(if (and host (string-match "%[0-9][0-9]" host))
(setq host (url-unhex-string host)))
(url-parse-make-urlobj scheme user pass host port file
fragment nil full))))))

View file

@ -166,6 +166,27 @@
(url-parse-make-urlobj "http" nil nil "банки.рф" nil
"/фыва/" nil nil t))))
(ert-deftest url-generic-parse-url/ms-windows-file-uri-hanlding ()
"bug#76982 Make an exception if a URI refers to a filename and it \"looks like\" a Windows path: strip the leading /"
(should (equal (url-generic-parse-url "file:///c:/windows-path") (url-parse-make-urlobj "file" nil nil "" nil "c:/windows-path" nil nil t)))
(should (equal (url-filename (url-generic-parse-url "file:///c:/directory/file.txt")) "c:/directory/file.txt"))
(should (equal (url-recreate-url (url-parse-make-urlobj "file" nil nil "" nil "c:/directory/file.txt" nil nil t)) "file:///c:/directory/file.txt"))
;; https://www.rfc-editor.org/rfc/rfc8089.html#appendix-E.2
(should (equal (url-generic-parse-url "file:c:/path/to/file") (url-parse-make-urlobj "file" nil nil nil nil "c:/path/to/file" nil nil nil)))
(should (equal (url-recreate-url (url-parse-make-urlobj "file" nil nil nil nil "c:/path/to/file" nil nil nil)) "file:c:/path/to/file"))
;; accept backslashes too
(should (equal (url-filename (url-generic-parse-url "file:///c:\\directory\\file.txt")) "c:\\directory\\file.txt"))
;;
(should (equal (url-filename (url-generic-parse-url "file://localhost/c:/path/to/file")) "c:/path/to/file"))
)
(provide 'url-parse-tests)
;;; url-parse-tests.el ends here