>From 81e2668d2d20025c38f780b9238e722f5d4e0317 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 13 Dec 2022 00:23:58 -0800 Subject: [PATCH 0/5] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (5): ; Be nicer when updating browse-url var in erc-compat Actually accept non-symbols as IDs in erc-open Limit casemapping to appropriate ranges in ERC Set erc-network to a "given" ID instead of failing Add escape hatch for picky servers in erc-sasl lisp/erc/erc-common.el | 16 +++----- lisp/erc/erc-compat.el | 7 +++- lisp/erc/erc-networks.el | 34 +++++++++++------ lisp/erc/erc-sasl.el | 33 ++++++++++++++--- lisp/erc/erc.el | 37 +++++++++++++------ test/lisp/erc/erc-networks-tests.el | 2 + .../erc/erc-scenarios-base-netid-samenet.el | 3 ++ test/lisp/erc/erc-tests.el | 3 ++ .../resources/base/local-modules/fourth.eld | 2 +- .../erc/resources/erc-scenarios-common.el | 2 +- 10 files changed, 95 insertions(+), 44 deletions(-) Interdiff: diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index 884abaf824..77625398ab 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el @@ -389,17 +389,13 @@ erc-compat--29-browse-url-irc url-irc-function))) (url-irc url))) -(declare-function cl-adjoin "cl-lib" (arg1 arg2 &rest rest)) - (cond ((fboundp 'browse-url-irc)) ; 29 ((boundp 'browse-url-default-handlers) ; 28 - (require 'cl-lib) - (cl-pushnew '("\\`irc6?s?://" . erc-compat--29-browse-url-irc) - browse-url-default-handlers - :key #'car - :test (lambda (_ b) - (and (stringp b) - (string-match-p b "irc://localhost"))))) + (setf (alist-get "\\`irc6?s?://" browse-url-default-handlers + nil nil (lambda (a _) + (and (stringp a) + (string-match-p a "irc://localhost")))) + #'erc-compat--29-browse-url-irc)) ((boundp 'browse-url-browser-function) ; 27 (require 'browse-url) (let ((existing browse-url-browser-function)) diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index 19a7ab8643..51ba54f45c 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -60,6 +60,7 @@ erc-session-server (declare-function erc-buffer-filter "erc" (predicate &optional proc)) (declare-function erc-current-nick "erc" nil) (declare-function erc-display-error-notice "erc" (parsed string)) +(declare-function erc-display-message "erc" (parsed type buffer msg &rest args)) (declare-function erc-error "erc" (&rest args)) (declare-function erc-get-buffer "erc" (target &optional proc)) (declare-function erc-server-buffer "erc" nil) @@ -1260,21 +1261,31 @@ erc-networks--determine return name) (and-let* ((vanity (erc--get-isupport-entry 'NETWORK 'single)) ((intern vanity)))) + (erc-networks--id-given erc-networks--id) erc-networks--name-missing-sentinel)) -(defun erc-networks--set-name (_proc parsed) +(defun erc-networks--set-name (proc parsed) "Set `erc-network' to the value returned by `erc-networks--determine'. -Signal an error when the network cannot be determined." +Signal an error when the network cannot be determined after first +shutting down the connection." ;; Always update (possibly clobber) current value, if any. (let ((name (erc-networks--determine))) + (when (eq name (erc-networks--id-given erc-networks--id)) + (let ((m (format "Couldn't determine network. Using given ID `%s'." + name))) + (erc-display-message parsed 'notice nil m))) (when (eq name erc-networks--name-missing-sentinel) - ;; This can happen theoretically, e.g., if you're editing some - ;; settings interactively on a proxy service that impersonates IRC - ;; but aren't being proxied through to a real network. The + ;; This can happen theoretically, e.g., when adjusting settings + ;; on a proxy service that partially impersonates IRC but isn't + ;; currently conveying anything through to a real network. The ;; service may send a 422 but no NETWORK param (or *any* 005s). - (let ((m (concat "Failed to determine network. Please set entry for " - erc-server-announced-name " in `erc-networks-alist'."))) + (let ((m (concat "Failed to determine network. Please set entry for \"" + erc-server-announced-name "\" in `erc-networks-alist'" + " or consider calling `erc-tls' with the keyword `:id'." + " See Info:\"(erc) Network Identifier\" for more."))) (erc-display-error-notice parsed m) + (run-hook-with-args 'erc-quit-hook proc) + (delete-process proc) (erc-error "Failed to determine network"))) ; beep (setq erc-network name)) nil) @@ -1287,11 +1298,12 @@ erc-networks--ensure-announced Copy source (prefix) from MOTD-ish message as a last resort." ;; The 004 handler never ran; see 2004-03-10 Diane Murray in change log (unless erc-server-announced-name - (erc-display-error-notice parsed "Failed to determine server name.") + (setq erc-server-announced-name (erc-response.sender parsed)) (erc-display-error-notice - parsed (concat "If this was unexpected, consider reporting it via " - (substitute-command-keys "\\[erc-bug]") ".")) - (setq erc-server-announced-name (erc-response.sender parsed))) + parsed (concat "Failed to determine server name. Using \"" + erc-server-announced-name "\" instead." + " If this was unexpected, consider reporting it via " + (substitute-command-keys "\\[erc-bug]") "."))) nil) (defun erc-unset-network-name (_nick _ip _reason) diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el index 5b2c93988a..9486250529 100644 --- a/lisp/erc/erc-sasl.el +++ b/lisp/erc/erc-sasl.el @@ -414,17 +414,38 @@ erc-sasl--destroy " ")) (erc-sasl--destroy proc)) +;; The rationale for not enabling this by default is twofold: +;; +;; - It more strongly implies that ERC supports client capability +;; negotiation, which is therefore more disingenuous. +;; +;; - We'd still be "faking it" by firing and forgetting, and more +;; balls in the air makes things less predictable. + +(defvar erc-sasl--send-cap-ls nil + "Whether to send an opening \"CAP LS\" command. +This is an escape hatch for picky servers expecting this command. +If you need this, please let us know via \\[erc-bug], so we can +offer a user option instead.") + (cl-defmethod erc--register-connection (&context (erc-sasl-mode (eql t))) - "Send speculative/pipelined CAP and AUTHENTICATE and hope for the best." + "Send speculative CAP and pipelined AUTHENTICATE and hope for the best." (if-let* ((c (erc-sasl--state-client erc-sasl--state)) (m (sasl-mechanism-name (sasl-client-mechanism c)))) (progn - (erc-server-send "CAP REQ :sasl") - (if (and erc-session-password - (eq :password (alist-get 'password erc-sasl--options))) - (let (erc-session-password) - (erc-login)) + (erc-server-send (if erc-sasl--send-cap-ls "CAP LS" "CAP REQ :sasl")) + (let ((erc-session-password + (and erc-session-password + (not (eq :password (alist-get 'password erc-sasl--options))) + erc-session-password)) + (erc-session-username + ;; The username may contain a colon or a space + (if (eq :user (alist-get 'user erc-sasl--options)) + (erc-current-nick) + erc-session-username))) (erc-login)) + (when erc-sasl--send-cap-ls + (erc-server-send "CAP REQ :sasl")) (erc-server-send (format "AUTHENTICATE %s" m))) (erc-sasl--destroy erc-server-process))) diff --git a/test/lisp/erc/erc-networks-tests.el b/test/lisp/erc/erc-networks-tests.el index fc12bf7ce3..02fc57d4e6 100644 --- a/test/lisp/erc/erc-networks-tests.el +++ b/test/lisp/erc/erc-networks-tests.el @@ -1171,6 +1171,8 @@ erc-networks--set-name (let (erc-server-announced-name (erc--isupport-params (make-hash-table)) erc-network + erc-quit-hook + (erc-server-process (erc-networks-tests--create-live-proc)) calls) (erc-mode) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index e30452b1cf..51c562f525 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -428,21 +428,21 @@ erc-downcase (ert-info ("ascii") (puthash 'CASEMAPPING '("ascii") erc--isupport-params) - (should (equal (erc-downcase "ABC 123 ΣΛΣΝΟΣ") "abc 123 ΣΛΣΝΟΣ")) + (should (equal (erc-downcase "ABC 123 ΔΞΩΣ") "abc 123 ΔΞΩΣ")) (should (equal (erc-downcase "Bob[m]`") "bob[m]`")) (should (equal (erc-downcase "Tilde~") "tilde~" )) (should (equal (erc-downcase "\\O/") "\\o/" ))) (ert-info ("rfc1459") (puthash 'CASEMAPPING '("rfc1459") erc--isupport-params) - (should (equal (erc-downcase "ABC 123 ΣΛΣΝΟΣ") "abc 123 ΣΛΣΝΟΣ")) + (should (equal (erc-downcase "ABC 123 ΔΞΩΣ") "abc 123 ΔΞΩΣ")) (should (equal (erc-downcase "Bob[m]`") "bob{m}`" )) (should (equal (erc-downcase "Tilde~") "tilde^" )) (should (equal (erc-downcase "\\O/") "|o/" ))) (ert-info ("rfc1459-strict") (puthash 'CASEMAPPING '("rfc1459-strict") erc--isupport-params) - (should (equal (erc-downcase "ABC 123 ΣΛΣΝΟΣ") "abc 123 ΣΛΣΝΟΣ")) + (should (equal (erc-downcase "ABC 123 ΔΞΩΣ") "abc 123 ΔΞΩΣ")) (should (equal (erc-downcase "Bob[m]`") "bob{m}`")) (should (equal (erc-downcase "Tilde~") "tilde~" )) (should (equal (erc-downcase "\\O/") "|o/" ))))) diff --git a/test/lisp/erc/resources/base/local-modules/fourth.eld b/test/lisp/erc/resources/base/local-modules/fourth.eld index fd6d62b6cc..4ac5dcbd38 100644 --- a/test/lisp/erc/resources/base/local-modules/fourth.eld +++ b/test/lisp/erc/resources/base/local-modules/fourth.eld @@ -1,7 +1,7 @@ ;; -*- mode: lisp-data; -*- ((cap 10 "CAP REQ :sasl")) ((nick 10 "NICK tester`")) -((user 10 "USER tester 0 * :tester")) +((user 10 "USER tester` 0 * :tester")) ((authenticate 10 "AUTHENTICATE PLAIN") (0.0 ":irc.foonet.org CAP * ACK sasl") -- 2.38.1