;; 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) "//")
;; 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)))
(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))))))
(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