summaryrefslogtreecommitdiff
path: root/lisp/url/url-util.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2022-09-25 16:15:16 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2022-09-25 16:15:16 -0400
commit650c20f1ca4e07591a727e1cfcc74b3363d15985 (patch)
tree85d11f6437cde22f410c25e0e5f71a3131ebd07d /lisp/url/url-util.el
parent8869332684c2302b5ba1ead4568bbc7ba1c0183e (diff)
parent4b85ae6a24380fb67a3315eaec9233f17a872473 (diff)
downloademacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.tar.gz
emacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.tar.bz2
emacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.zip
Merge 'master' into noverlay
Diffstat (limited to 'lisp/url/url-util.el')
-rw-r--r--lisp/url/url-util.el230
1 files changed, 105 insertions, 125 deletions
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 1d9e386bbc3..147a643c9fd 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -1,7 +1,6 @@
;;; url-util.el --- Miscellaneous helper routines for URL library -*- lexical-binding: t -*-
-;; Copyright (C) 1996-1999, 2001, 2004-2017 Free Software Foundation,
-;; Inc.
+;; Copyright (C) 1996-2022 Free Software Foundation, Inc.
;; Author: Bill Perry <wmperry@gnu.org>
;; Maintainer: emacs-devel@gnu.org
@@ -28,8 +27,6 @@
(require 'url-parse)
(require 'url-vars)
-(autoload 'timezone-parse-date "timezone")
-(autoload 'timezone-make-date-arpa-standard "timezone")
(autoload 'mail-header-extract "mailheader")
(defvar url-parse-args-syntax-table
@@ -61,8 +58,6 @@ If a list, it is a list of the types of messages to be logged."
;;;###autoload
(defun url-debug (tag &rest args)
- (if quit-flag
- (error "Interrupted!"))
(if (or (eq url-debug t)
(numberp url-debug)
(and (listp url-debug) (memq tag url-debug)))
@@ -74,61 +69,51 @@ If a list, it is a list of the types of messages to be logged."
;;;###autoload
(defun url-parse-args (str &optional nodowncase)
- ;; Return an assoc list of attribute/value pairs from an RFC822-type string
- (let (
- name ; From name=
+ ;; Return an assoc list of attribute/value pairs from a string
+ ;; that uses RFC 822 (or later) format.
+ (let (name ; From name=
value ; its value
results ; Assoc list of results
name-pos ; Start of XXXX= position
- val-pos ; Start of value position
- st
- nd
- )
- (save-excursion
- (save-restriction
- (set-buffer (get-buffer-create " *urlparse-temp*"))
- (set-syntax-table url-parse-args-syntax-table)
- (erase-buffer)
- (insert str)
- (setq st (point-min)
- nd (point-max))
- (set-syntax-table url-parse-args-syntax-table)
- (narrow-to-region st nd)
- (goto-char (point-min))
- (while (not (eobp))
- (skip-chars-forward "; \n\t")
- (setq name-pos (point))
- (skip-chars-forward "^ \n\t=;")
- (if (not nodowncase)
- (downcase-region name-pos (point)))
- (setq name (buffer-substring name-pos (point)))
- (skip-chars-forward " \t\n")
- (if (/= (or (char-after (point)) 0) ?=) ; There is no value
- (setq value nil)
- (skip-chars-forward " \t\n=")
- (setq val-pos (point)
- value
- (cond
- ((or (= (or (char-after val-pos) 0) ?\")
- (= (or (char-after val-pos) 0) ?'))
- (buffer-substring (1+ val-pos)
- (condition-case ()
- (prog2
- (forward-sexp 1)
- (1- (point))
- (skip-chars-forward "\""))
- (error
- (skip-chars-forward "^ \t\n")
- (point)))))
- (t
- (buffer-substring val-pos
- (progn
- (skip-chars-forward "^;")
- (skip-chars-backward " \t")
- (point)))))))
- (setq results (cons (cons name value) results))
- (skip-chars-forward "; \n\t"))
- results))))
+ val-pos) ; Start of value position
+ (with-temp-buffer
+ (insert str)
+ (set-syntax-table url-parse-args-syntax-table)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (skip-chars-forward "; \n\t")
+ (setq name-pos (point))
+ (skip-chars-forward "^ \n\t=;")
+ (unless nodowncase
+ (downcase-region name-pos (point)))
+ (setq name (buffer-substring name-pos (point)))
+ (skip-chars-forward " \t\n")
+ (if (/= (or (char-after (point)) 0) ?=) ; There is no value
+ (setq value nil)
+ (skip-chars-forward " \t\n=")
+ (setq val-pos (point)
+ value
+ (cond
+ ((or (= (or (char-after val-pos) 0) ?\")
+ (= (or (char-after val-pos) 0) ?'))
+ (buffer-substring (1+ val-pos)
+ (condition-case ()
+ (prog2
+ (forward-sexp 1)
+ (1- (point))
+ (skip-chars-forward "\""))
+ (error
+ (skip-chars-forward "^ \t\n")
+ (point)))))
+ (t
+ (buffer-substring val-pos
+ (progn
+ (skip-chars-forward "^;")
+ (skip-chars-backward " \t")
+ (point)))))))
+ (setq results (cons (cons name value) results))
+ (skip-chars-forward "; \n\t"))
+ results)))
;;;###autoload
(defun url-insert-entities-in-string (string)
@@ -182,7 +167,7 @@ Will not do anything if `url-show-status' is nil."
(null url-show-status)
(active-minibuffer-window)
(= url-lazy-message-time
- (setq url-lazy-message-time (nth 1 (current-time)))))
+ (setq url-lazy-message-time (time-convert nil 'integer))))
nil
(apply 'message args)))
@@ -193,45 +178,32 @@ Will not do anything if `url-show-status' is nil."
(format-time-string "%a, %d %b %Y %T GMT" specified-time t)))
;;;###autoload
-(defun url-eat-trailing-space (x)
- "Remove spaces/tabs at the end of a string."
- (let ((y (1- (length x)))
- (skip-chars (list ? ?\t ?\n)))
- (while (and (>= y 0) (memq (aref x y) skip-chars))
- (setq y (1- y)))
- (substring x 0 (1+ y))))
+(define-obsolete-function-alias 'url-eat-trailing-space
+ #'string-trim-right "29.1")
;;;###autoload
-(defun url-strip-leading-spaces (x)
- "Remove spaces at the front of a string."
- (let ((y (1- (length x)))
- (z 0)
- (skip-chars (list ? ?\t ?\n)))
- (while (and (<= z y) (memq (aref x z) skip-chars))
- (setq z (1+ z)))
- (substring x z nil)))
-
+(define-obsolete-function-alias 'url-strip-leading-spaces
+ #'string-trim-left "29.1")
(define-obsolete-function-alias 'url-pretty-length
'file-size-human-readable "24.4")
;;;###autoload
-(defun url-display-percentage (fmt perc &rest args)
+(defun url-display-message (fmt &rest args)
+ "Like `message', but do nothing if `url-show-status' is nil."
(when (and url-show-status
- (or (null url-current-object)
- (not (url-silent url-current-object))))
- (if (null fmt)
- (if (fboundp 'clear-progress-display)
- (clear-progress-display))
- (if (and (fboundp 'progress-display) perc)
- (apply 'progress-display fmt perc args)
- (apply 'message fmt args)))))
+ (not (and url-current-object (url-silent url-current-object)))
+ fmt)
+ (apply #'message fmt args)))
+
+;;;###autoload
+(defun url-display-percentage (fmt _perc &rest args)
+ (declare (obsolete url-display-message "29.1"))
+ (url-display-message fmt args))
;;;###autoload
(defun url-percentage (x y)
- (if (fboundp 'float)
- (round (* 100 (/ x (float y))))
- (/ (* x 100) y)))
+ (round (* 100 (/ x (float y)))))
;;;###autoload
(defalias 'url-basepath 'url-file-directory)
@@ -264,7 +236,7 @@ Will not do anything if `url-show-status' is nil."
(while pairs
(setq cur (car pairs)
pairs (cdr pairs))
- (unless (string-match "=" cur)
+ (unless (string-search "=" cur)
(setq cur (concat cur "=")))
(when (string-match "=" cur)
@@ -294,7 +266,7 @@ Given a QUERY in the form:
\(This is the same format as produced by `url-parse-query-string')
This will return a string
-\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
+\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
be strings or symbols; if they are symbols, the symbol name will
be used.
@@ -347,10 +319,13 @@ instead of just \"key\" as in the example above."
;;;###autoload
(defun url-unhex-string (str &optional allow-newlines)
- "Remove %XX embedded spaces, etc in a URL.
+ "Decode %XX sequences in a percent-encoded URL.
If optional second argument ALLOW-NEWLINES is non-nil, then allow the
decoding of carriage returns and line feeds in the string, which is normally
-forbidden in URL encoding."
+forbidden in URL encoding.
+
+The resulting string in general requires decoding using an
+appropriate coding-system; see `decode-coding-string'."
(setq str (or str ""))
(let ((tmp "")
(case-fold-search t))
@@ -407,9 +382,12 @@ string: \"%\" followed by two upper-case hex digits.
The allowed characters are specified by ALLOWED-CHARS. If this
argument is nil, the list `url-unreserved-chars' determines the
-allowed characters. Otherwise, ALLOWED-CHARS should be a vector
-whose Nth element is non-nil if character N is allowed."
- (unless allowed-chars
+allowed characters. Otherwise, ALLOWED-CHARS should be either a
+list of allowed chars, or a vector whose Nth element is non-nil
+if character N is allowed."
+ (if allowed-chars
+ (unless (vectorp allowed-chars)
+ (setq allowed-chars (url--allowed-chars allowed-chars)))
(setq allowed-chars (url--allowed-chars url-unreserved-chars)))
(mapconcat (lambda (byte)
(if (aref allowed-chars byte)
@@ -502,7 +480,7 @@ WIDTH defaults to the current frame width."
(urlobj nil))
;; The first thing that can go are the search strings
(if (and (>= str-width fr-width)
- (string-match "?" url))
+ (string-match "\\?" url))
(setq url (concat (substring url 0 (match-beginning 0)) "?...")
str-width (length url)))
(if (< str-width fr-width)
@@ -544,6 +522,7 @@ This uses `url-current-object', set locally to the buffer."
(defun url-get-url-at-point (&optional pt)
"Get the URL closest to point, but don't change position.
Has a preference for looking backward when not directly on a symbol."
+ (declare (obsolete thing-at-point-url-at-point "27.1"))
;; Not at all perfect - point must be right in the name.
(save-excursion
(if pt (goto-char pt))
@@ -577,38 +556,13 @@ Has a preference for looking backward when not directly on a symbol."
(setq url nil))
url)))
-(defun url-generate-unique-filename (&optional fmt)
- "Generate a unique filename in `url-temporary-directory'."
- (declare (obsolete make-temp-file "23.1"))
- ;; This variable is obsolete, but so is this function.
- (let ((tempdir (with-no-warnings url-temporary-directory)))
- (if (not fmt)
- (let ((base (format "url-tmp.%d" (user-real-uid)))
- (fname "")
- (x 0))
- (setq fname (format "%s%d" base x))
- (while (file-exists-p
- (expand-file-name fname tempdir))
- (setq x (1+ x)
- fname (concat base (int-to-string x))))
- (expand-file-name fname tempdir))
- (let ((base (concat "url" (int-to-string (user-real-uid))))
- (fname "")
- (x 0))
- (setq fname (format fmt (concat base (int-to-string x))))
- (while (file-exists-p
- (expand-file-name fname tempdir))
- (setq x (1+ x)
- fname (format fmt (concat base (int-to-string x)))))
- (expand-file-name fname tempdir)))))
-
(defun url-extract-mime-headers ()
"Set `url-current-mime-headers' in current buffer."
(save-excursion
(goto-char (point-min))
(unless url-current-mime-headers
- (set (make-local-variable 'url-current-mime-headers)
- (mail-header-extract)))))
+ (setq-local url-current-mime-headers
+ (mail-header-extract)))))
(defun url-make-private-file (file)
"Make FILE only readable and writable by the current user.
@@ -623,9 +577,35 @@ Creates FILE and its parent directories if they do not exist."
(with-temp-buffer
(write-region (point-min) (point-max) file nil 'silent nil 'excl)))
(file-already-exists
- (if (file-symlink-p file)
- (error "Danger: `%s' is a symbolic link" file))
- (set-file-modes file #o0600))))
+ (set-file-modes file #o0600 'nofollow))))
+
+(autoload 'puny-encode-domain "puny")
+(autoload 'url-domsuf-cookie-allowed-p "url-domsuf")
+
+;;;###autoload
+(defun url-domain (url)
+ "Return the domain of the host of the URL.
+Return nil if this can't be determined.
+
+For instance, this function will return \"fsf.co.uk\" if the host in URL
+is \"www.fsf.co.uk\"."
+ (let* ((host (puny-encode-domain (url-host url)))
+ (parts (nreverse (split-string host "\\.")))
+ (candidate (pop parts))
+ found)
+ ;; IP addresses aren't domains.
+ (when (string-match "\\`[0-9.]+\\'" host)
+ (setq parts nil))
+ ;; We assume that the top-level domain is never an appropriate
+ ;; thing as "the domain", so we start at the next one (eg.
+ ;; "fsf.org").
+ (while (and parts
+ (not (setq found
+ (url-domsuf-cookie-allowed-p
+ (setq candidate (concat (pop parts) "."
+ candidate))))))
+ )
+ (and found candidate)))
(provide 'url-util)