diff options
| author | Noam Postavsky | 2019-06-16 13:48:56 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2019-06-22 19:25:44 -0400 |
| commit | f46b16b9fb00d341f222422a9514f5bd62f29971 (patch) | |
| tree | e42e73ce40e790018f6a3cdf88af5bb141fb1d8a | |
| parent | 96ebbf44b076b165943caefc1bbb0ff4c0f12b6b (diff) | |
| download | emacs-f46b16b9fb00d341f222422a9514f5bd62f29971.tar.gz emacs-f46b16b9fb00d341f222422a9514f5bd62f29971.zip | |
Make rcirc parsing more RFC2812 compliant (Bug#36233)
Do continue to allow multiple spaces between arguments, even though
that is technically not allowed by the RFC.
* lisp/net/rcirc.el (rcirc-process-server-response-1): Fix parsing of
arguments which contain colons.
* test/lisp/net/rcirc-tests.el: New test.
| -rw-r--r-- | lisp/net/rcirc.el | 27 | ||||
| -rw-r--r-- | test/lisp/net/rcirc-tests.el | 52 |
2 files changed, 71 insertions, 8 deletions
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 8926772b944..24084c828e1 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el | |||
| @@ -774,22 +774,33 @@ Function is called with PROCESS, COMMAND, SENDER, ARGS and LINE.") | |||
| 774 | (rcirc-process-server-response-1 process text))) | 774 | (rcirc-process-server-response-1 process text))) |
| 775 | 775 | ||
| 776 | (defun rcirc-process-server-response-1 (process text) | 776 | (defun rcirc-process-server-response-1 (process text) |
| 777 | (if (string-match "^\\(:\\([^ ]+\\) \\)?\\([^ ]+\\) \\(.+\\)$" text) | 777 | ;; See https://tools.ietf.org/html/rfc2812#section-2.3.1. We're a |
| 778 | ;; bit more accepting than the RFC: We allow any non-space | ||
| 779 | ;; characters in the command name, multiple spaces between | ||
| 780 | ;; arguments, and allow the last argument to omit the leading ":", | ||
| 781 | ;; even if there are less than 15 arguments. | ||
| 782 | (if (string-match "^\\(:\\([^ ]+\\) \\)?\\([^ ]+\\)" text) | ||
| 778 | (let* ((user (match-string 2 text)) | 783 | (let* ((user (match-string 2 text)) |
| 779 | (sender (rcirc-user-nick user)) | 784 | (sender (rcirc-user-nick user)) |
| 780 | (cmd (match-string 3 text)) | 785 | (cmd (match-string 3 text)) |
| 781 | (args (match-string 4 text)) | 786 | (cmd-end (match-end 3)) |
| 787 | (args nil) | ||
| 782 | (handler (intern-soft (concat "rcirc-handler-" cmd)))) | 788 | (handler (intern-soft (concat "rcirc-handler-" cmd)))) |
| 783 | (string-match "^\\([^:]*\\):?\\(.+\\)?$" args) | 789 | (cl-loop with i = cmd-end |
| 784 | (let* ((args1 (match-string 1 args)) | 790 | repeat 14 |
| 785 | (args2 (match-string 2 args)) | 791 | while (eql i (string-match " +\\([^: ][^ ]*\\)" text i)) |
| 786 | (args (delq nil (append (split-string args1 " " t) | 792 | do (progn (push (match-string 1 text) args) |
| 787 | (list args2))))) | 793 | (setq i (match-end 0))) |
| 794 | finally | ||
| 795 | (progn (if (eql i (string-match " +:?" text i)) | ||
| 796 | (push (substring text (match-end 0)) args) | ||
| 797 | (cl-assert (= i (length text)))) | ||
| 798 | (cl-callf nreverse args))) | ||
| 788 | (if (not (fboundp handler)) | 799 | (if (not (fboundp handler)) |
| 789 | (rcirc-handler-generic process cmd sender args text) | 800 | (rcirc-handler-generic process cmd sender args text) |
| 790 | (funcall handler process sender args text)) | 801 | (funcall handler process sender args text)) |
| 791 | (run-hook-with-args 'rcirc-receive-message-functions | 802 | (run-hook-with-args 'rcirc-receive-message-functions |
| 792 | process cmd sender args text))) | 803 | process cmd sender args text)) |
| 793 | (message "UNHANDLED: %s" text))) | 804 | (message "UNHANDLED: %s" text))) |
| 794 | 805 | ||
| 795 | (defvar rcirc-responses-no-activity '("305" "306") | 806 | (defvar rcirc-responses-no-activity '("305" "306") |
diff --git a/test/lisp/net/rcirc-tests.el b/test/lisp/net/rcirc-tests.el new file mode 100644 index 00000000000..128cb2e7540 --- /dev/null +++ b/test/lisp/net/rcirc-tests.el | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | ;;; rcirc-tests.el --- Tests for rcirc -*- lexical-binding:t -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2019 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This program is free software: you can redistribute it and/or | ||
| 6 | ;; modify it under the terms of the GNU General Public License as | ||
| 7 | ;; published by the Free Software Foundation, either version 3 of the | ||
| 8 | ;; License, or (at your option) any later version. | ||
| 9 | ;; | ||
| 10 | ;; This program is distributed in the hope that it will be useful, but | ||
| 11 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | ;; General Public License for more details. | ||
| 14 | ;; | ||
| 15 | ;; You should have received a copy of the GNU General Public License | ||
| 16 | ;; along with this program. If not, see `https://www.gnu.org/licenses/'. | ||
| 17 | |||
| 18 | ;;; Code: | ||
| 19 | |||
| 20 | (require 'ert) | ||
| 21 | (require 'rcirc) | ||
| 22 | (require 'cl-lib) | ||
| 23 | |||
| 24 | (defun rcirc-tests--parse-server-response (cmd text) | ||
| 25 | (cl-letf* ((received-args nil) | ||
| 26 | ((symbol-function (intern (concat "rcirc-handler-" cmd))) | ||
| 27 | (lambda (_process sender args text) | ||
| 28 | (setq received-args (list sender cmd args text)))) | ||
| 29 | (rcirc-receive-message-functions nil) | ||
| 30 | (rcirc-trap-errors-flag nil)) | ||
| 31 | (rcirc-process-server-response nil text) | ||
| 32 | received-args)) | ||
| 33 | |||
| 34 | (defmacro rcirc-tests--server-response-parse-should-be | ||
| 35 | (text expected-sender expected-cmd expected-args) | ||
| 36 | (declare (debug t)) | ||
| 37 | (macroexp-let2* nil ((cmd expected-cmd)) | ||
| 38 | `(should (equal (rcirc-tests--parse-server-response ,cmd ,text) | ||
| 39 | (list ,expected-sender ,cmd ,expected-args ,text))))) | ||
| 40 | |||
| 41 | (ert-deftest rcirc-process-server-response () | ||
| 42 | (rcirc-tests--server-response-parse-should-be | ||
| 43 | "MODE #cchan +kl a:b :999" | ||
| 44 | nil "MODE" '("#cchan" "+kl" "a:b" "999")) | ||
| 45 | (rcirc-tests--server-response-parse-should-be | ||
| 46 | "MODE #cchan +kl a:b 999" | ||
| 47 | nil "MODE" '("#cchan" "+kl" "a:b" "999")) | ||
| 48 | (rcirc-tests--server-response-parse-should-be | ||
| 49 | "MODE #cchan +kl :a:b" | ||
| 50 | nil "MODE" '("#cchan" "+kl" "a:b"))) | ||
| 51 | |||
| 52 | ;;; rcirc-tests.el ends here | ||