From 241e91980886e48579e74a7f739079547f7d73fd Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sun, 18 Aug 2024 22:58:11 -0700 Subject: [PATCH 4/5] [5.6.1] Use 5.6 MODE framework to update erc-channel-banlist * lisp/erc/erc-backend.el (erc-server-MODE): Don't call `erc-banlist-update'. * lisp/erc/erc.el (erc-banlist-finished): Deprecate function unused since 2003. (erc--banlist-update): New function. (erc-banlist-update): Deprecate function because its logic is faulty and it doesn't handle mixed mode letters, like "MODE #foobar +mb *@127.0.0.1". See https://modern.ircdocs.horse/#mode-message. It also depends on an obsolete convention regarding the symbol property `received-from-server' of `erc-channel-banlist'. Basically, this function used to run upon receipt of any "MODE" command from the server. However, actual updates to the variable `erc-channel-banlist' only happened if `received-from-server' was t, which could only be the case after the user issued a /MASSUNBAN. And that behavior was determined to be a bug. This mode framework stuff was introduced as part of bug#67220 for ERC 5.6. (erc--handle-channel-mode): New method. * test/lisp/erc/erc-tests.el (erc--channel-modes) (erc--channel-modes/graphic-p): Assert contents of `erc-channel-banlist' updated on "MODE". --- lisp/erc/erc-backend.el | 4 ++-- lisp/erc/erc.el | 19 +++++++++++++++++++ test/lisp/erc/erc-tests.el | 17 +++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index d999cf57db8..16e8cae4733 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -1851,8 +1851,8 @@ erc--server-determine-join-display-context ?t tgt ?m mode) (erc-display-message parsed 'notice buf 'MODE ?n nick ?u login - ?h host ?t tgt ?m mode))) - (erc-banlist-update proc parsed)))) + ?h host ?t tgt ?m mode))))) + nil) (defun erc--wrangle-query-buffers-on-nick-change (old new) "Create or reuse a query buffer for NEW nick after considering OLD nick. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 8b3eef94ee4..e1fd279f405 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -6639,17 +6639,31 @@ erc-banlist-store erc-channel-banlist)))))) nil) +;; This was a default member of `erc-server-368-functions' (nee -hook) +;; between January and June of 2003 (but not as part of any release). (defun erc-banlist-finished (proc parsed) "Record that we have received the banlist." + (declare (obsolete "uses obsolete and likely faulty logic" "31.1")) (let* ((channel (nth 1 (erc-response.command-args parsed))) (buffer (erc-get-buffer channel proc))) (with-current-buffer buffer (put 'erc-channel-banlist 'received-from-server t))) t) ; suppress the 'end of banlist' message +(defun erc--banlist-update (statep mask) + "Add or remove a mask from `erc-channel-banlist'." + (if statep + (let ((whoset (erc-response.sender erc--parsed-response))) + (cl-pushnew (cons whoset mask) erc-channel-banlist :test #'equal)) + (let ((upcased (upcase mask))) + (setq erc-channel-banlist + (cl-delete-if (lambda (y) (equal (upcase (cdr y)) upcased)) + erc-channel-banlist))))) + (defun erc-banlist-update (proc parsed) "Check MODE commands for bans and update the banlist appropriately." ;; FIXME: Possibly incorrect. -- Lawrence 2004-05-11 + (declare (obsolete "`erc-channel-banlist' always updated on MODE" "31.1")) (let* ((tgt (car (erc-response.command-args parsed))) (mode (erc-response.contents parsed)) (whoset (erc-response.sender parsed)) @@ -7732,6 +7746,11 @@ erc--handle-channel-mode (cl-pushnew (char-to-string c) erc-channel-modes :test #'equal) (delete (char-to-string c) erc-channel-modes)))) +;; We could specialize on type A, but that may be too brittle. +(cl-defmethod erc--handle-channel-mode (_ (_ (eql ?b)) state arg) + ;; Add or remove a ban from `erc-channel-banlist'. + (erc--banlist-update state arg)) + ;; We could specialize on type C, but that may be too brittle. (cl-defmethod erc--handle-channel-mode (_ (_ (eql ?l)) state arg) "Update channel user limit, remembering ARG when STATE is non-nil." diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index b11f994bce8..560d3bbb3d0 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -934,8 +934,13 @@ erc--channel-modes (erc-tests-common-init-server-proc "sleep" "1") - (cl-letf (((symbol-function 'erc-update-mode-line) #'ignore)) - (erc--update-channel-modes "+bltk" "fool!*@*" "3" "h2")) + (cl-letf ((erc--parsed-response (make-erc-response + :sender "chop!~u@gnu.org")) + ((symbol-function 'erc-update-mode-line) #'ignore)) + (should-not erc-channel-banlist) + (erc--update-channel-modes "+bbltk" "fool!*@*" "spam!*@*" "3" "h2") + (should (equal erc-channel-banlist '(("chop!~u@gnu.org" . "spam!*@*") + ("chop!~u@gnu.org" . "fool!*@*"))))) (should (equal (erc--channel-modes 'string) "klt")) (should (equal (erc--channel-modes 'strings) '("k" "l" "t"))) @@ -983,8 +988,12 @@ erc--channel-modes/graphic-p erc-server-parameters '(("CHANMODES" . "eIbq,k,flj,CFLMPQRSTcgimnprstuz"))) - (cl-letf (((symbol-function 'erc-update-mode-line) #'ignore)) - (erc--update-channel-modes "+bltk" "fool!*@*" "3" "hun2")) + (cl-letf ((erc--parsed-response (make-erc-response + :sender "chop!~u@gnu.org")) + ((symbol-function 'erc-update-mode-line) #'ignore)) + (should-not erc-channel-banlist) + (erc--update-channel-modes "+bltk" "fool!*@*" "3" "hun2") + (should (equal erc-channel-banlist '(("chop!~u@gnu.org" . "fool!*@*"))))) ;; Truncation cache populated and used. (let ((cache (erc--channel-mode-types-shortargs erc--channel-mode-types)) -- 2.46.0