aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorF. Jason Park2023-04-17 00:01:15 -0700
committerF. Jason Park2023-05-05 17:18:01 -0700
commit3a5a6fce957468be5ef0a8ac76fec8507c3e4e99 (patch)
treeb51dca001d4de0382065b8dd5ffbaf651d15ae0b
parent16306567706c9621cef169d0e992b9b3b08a9d7e (diff)
downloademacs-3a5a6fce957468be5ef0a8ac76fec8507c3e4e99.tar.gz
emacs-3a5a6fce957468be5ef0a8ac76fec8507c3e4e99.zip
Redo line splitting for outgoing messages in ERC
* lisp/erc/erc-backend.el (erc--reject-unbreakable-lines): New variable, an escape hatch for somewhat regaining pre-5.6 line-splitting behavior. (erc--split-line): New utility function that doesn't rely on column-oriented filling. * lisp/erc/erc.el (erc--pre-send-split-functions): Append `erc--split-lines' to value. (erc--split-lines): New function to re-split current selection of lines. (erc-send-input): Hard-code line preparation instead of calling `erc--pre-send-split-functions', in order to bake in traditional behavior before move to "pre-splitting". * test/lisp/erc/erc-scenarios-base-split-line.el: New file. * test/lisp/erc/erc-tests.el (erc--split-line): New test. (erc-send-current-line): Don't expect a flood argument when interpreting a command because it's not passed along to the command's handler. This was previously misleading because it assigned undue significance to something that had no bearing on the fate of a command. * test/lisp/erc/resources/base/flood/ascii.eld: New file. * test/lisp/erc/resources/base/flood/koi8-r.eld: New file. * test/lisp/erc/resources/base/flood/utf-8.eld: New file. * test/lisp/erc/resources/erc-d/erc-d.el: Don't decode input. (Bug#62947)
-rw-r--r--lisp/erc/erc-backend.el41
-rw-r--r--lisp/erc/erc.el41
-rw-r--r--test/lisp/erc/erc-scenarios-base-split-line.el202
-rw-r--r--test/lisp/erc/erc-tests.el50
-rw-r--r--test/lisp/erc/resources/base/flood/ascii.eld49
-rw-r--r--test/lisp/erc/resources/base/flood/koi8-r.eld47
-rw-r--r--test/lisp/erc/resources/base/flood/utf-8.eld54
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d.el2
8 files changed, 467 insertions, 19 deletions
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 0c970a9d586..bc8e603e10a 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -572,6 +572,47 @@ If this is set to nil, never try to reconnect."
572 572
573;;;; Helper functions 573;;;; Helper functions
574 574
575(defvar erc--reject-unbreakable-lines nil
576 "Signal an error when a line exceeds `erc-split-line-length'.
577Sending such lines and hoping for the best is no longer supported
578in ERC 5.6. This internal var exists as a possibly temporary
579escape hatch for inhibiting their transmission.")
580
581(defun erc--split-line (longline)
582 (let* ((coding (erc-coding-system-for-target nil))
583 (original-window-buf (window-buffer (selected-window)))
584 out)
585 (when (consp coding)
586 (setq coding (car coding)))
587 (setq coding (coding-system-change-eol-conversion coding 'unix))
588 (unwind-protect
589 (with-temp-buffer
590 (set-window-buffer (selected-window) (current-buffer))
591 (insert longline)
592 (goto-char (point-min))
593 (while (not (eobp))
594 (let ((upper (filepos-to-bufferpos erc-split-line-length
595 'exact coding)))
596 (goto-char (or upper (point-max)))
597 (unless (eobp)
598 (skip-chars-backward "^ \t"))
599 (when (bobp)
600 (when erc--reject-unbreakable-lines
601 (user-error
602 (substitute-command-keys
603 (concat "Unbreakable line encountered "
604 "(Recover input with \\[erc-previous-command])"))))
605 (goto-char upper))
606 (when-let ((cmp (find-composition (point) (1+ (point)))))
607 (if (= (car cmp) (point-min))
608 (goto-char (nth 1 cmp))
609 (goto-char (car cmp)))))
610 (cl-assert (/= (point-min) (point)))
611 (push (buffer-substring-no-properties (point-min) (point)) out)
612 (delete-region (point-min) (point)))
613 (or (nreverse out) (list "")))
614 (set-window-buffer (selected-window) original-window-buf))))
615
575;; From Circe 616;; From Circe
576(defun erc-split-line (longline) 617(defun erc-split-line (longline)
577 "Return a list of lines which are not too long for IRC. 618 "Return a list of lines which are not too long for IRC.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 8552023804a..bc2285a5560 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -909,6 +909,9 @@ Flooding is sending too much information to the server in too
909short of an interval, which may cause the server to terminate the 909short of an interval, which may cause the server to terminate the
910connection. 910connection.
911 911
912Note that older code conflated rate limiting and line splitting.
913Starting in ERC 5.6, this option no longer influences the latter.
914
912See `erc-server-flood-margin' for other flood-related parameters.") 915See `erc-server-flood-margin' for other flood-related parameters.")
913 916
914;; Script parameters 917;; Script parameters
@@ -1103,7 +1106,8 @@ The struct has three slots:
1103;; remove this hook and the struct completely. IOW, if you need this, 1106;; remove this hook and the struct completely. IOW, if you need this,
1104;; please say so. 1107;; please say so.
1105 1108
1106(defvar erc--pre-send-split-functions '(erc--discard-trailing-multiline-nulls) 1109(defvar erc--pre-send-split-functions '(erc--discard-trailing-multiline-nulls
1110 erc--split-lines)
1107 "Special hook for modifying individual lines in multiline prompt input. 1111 "Special hook for modifying individual lines in multiline prompt input.
1108The functions are called with one argument, an `erc--input-split' 1112The functions are called with one argument, an `erc--input-split'
1109struct, which they can optionally modify. 1113struct, which they can optionally modify.
@@ -6211,6 +6215,14 @@ an `erc--input-split' object."
6211 (setq reversed (cdr reversed))) 6215 (setq reversed (cdr reversed)))
6212 (setf (erc--input-split-lines state) (nreverse reversed))))) 6216 (setf (erc--input-split-lines state) (nreverse reversed)))))
6213 6217
6218(defun erc--split-lines (state)
6219 "Partition non-command input into lines of protocol-compliant length."
6220 ;; Prior to ERC 5.6, line splitting used to be predicated on
6221 ;; `erc-flood-protect' being non-nil.
6222 (unless (erc--input-split-cmdp state)
6223 (setf (erc--input-split-lines state)
6224 (mapcan #'erc--split-line (erc--input-split-lines state)))))
6225
6214(defun erc-send-input (input &optional skip-ws-chk) 6226(defun erc-send-input (input &optional skip-ws-chk)
6215 "Treat INPUT as typed in by the user. 6227 "Treat INPUT as typed in by the user.
6216It is assumed that the input and the prompt is already deleted. 6228It is assumed that the input and the prompt is already deleted.
@@ -6241,23 +6253,22 @@ Return non-nil only if we actually send anything."
6241 :insertp erc-insert-this 6253 :insertp erc-insert-this
6242 :sendp erc-send-this)) 6254 :sendp erc-send-this))
6243 (run-hook-with-args 'erc-pre-send-functions state) 6255 (run-hook-with-args 'erc-pre-send-functions state)
6244 (setq state (make-erc--input-split
6245 :string (erc-input-string state)
6246 :insertp (erc-input-insertp state)
6247 :sendp (erc-input-sendp state)
6248 :lines (split-string (erc-input-string state)
6249 erc--input-line-delim-regexp)
6250 :cmdp (string-match erc-command-regexp
6251 (erc-input-string state))))
6252 (run-hook-with-args 'erc--pre-send-split-functions state)
6253 (when (and (erc-input-sendp state) 6256 (when (and (erc-input-sendp state)
6254 erc-send-this) 6257 erc-send-this)
6255 (let ((lines (erc--input-split-lines state))) 6258 (if-let* ((first (split-string (erc-input-string state)
6256 (if (and (erc--input-split-cmdp state) (not (cdr lines))) 6259 erc--input-line-delim-regexp))
6257 (erc-process-input-line (concat (car lines) "\n") t nil) 6260 (split (mapcan #'erc--split-line first))
6261 (lines (nreverse (seq-drop-while #'string-empty-p
6262 (nreverse split))))
6263 ((string-match erc-command-regexp (car lines))))
6264 (progn
6265 ;; Asking users what to do here might make more sense.
6266 (cl-assert (not (cdr lines)))
6267 ;; The `force' arg (here t) is ignored for command lines.
6268 (erc-process-input-line (concat (car lines) "\n") t nil))
6269 (progn ; temporarily preserve indentation
6258 (dolist (line lines) 6270 (dolist (line lines)
6259 (dolist (line (or (and erc-flood-protect (erc-split-line line)) 6271 (progn ; temporarily preserve indentation
6260 (list line)))
6261 (when (erc-input-insertp state) 6272 (when (erc-input-insertp state)
6262 (erc-display-msg line)) 6273 (erc-display-msg line))
6263 (erc-process-input-line (concat line "\n") 6274 (erc-process-input-line (concat line "\n")
diff --git a/test/lisp/erc/erc-scenarios-base-split-line.el b/test/lisp/erc/erc-scenarios-base-split-line.el
new file mode 100644
index 00000000000..f6d888c1f28
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-split-line.el
@@ -0,0 +1,202 @@
1;;; erc-scenarios-base-split-line.el --- ERC line splitting -*- lexical-binding: t -*-
2
3;; Copyright (C) 2023 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software: you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20;;; Code:
21
22(require 'ert-x)
23(eval-and-compile
24 (let ((load-path (cons (ert-resource-directory) load-path)))
25 (require 'erc-scenarios-common)))
26
27(ert-deftest erc-scenarios-base-split-line--koi8-r ()
28 :tags '(:expensive-test)
29 (should (equal erc-split-line-length 440))
30 (erc-scenarios-common-with-cleanup
31 ((erc-scenarios-common-dialog "base/flood")
32 (erc-server-flood-penalty 0.1)
33 (dumb-server (erc-d-run "localhost" t 'koi8-r))
34 (erc-encoding-coding-alist '(("#koi8" . cyrillic-koi8)))
35 (port (process-contact dumb-server :service))
36 (expect (erc-d-t-make-expecter)))
37
38 (ert-info ("Connect to server")
39 (with-current-buffer (erc :server "127.0.0.1"
40 :port port
41 :nick "tester"
42 :full-name "tester")
43 (funcall expect 10 "debug mode")
44 (erc-cmd-JOIN "#koi8")))
45
46 (with-current-buffer (erc-d-t-wait-for 8 (get-buffer "#koi8"))
47 (funcall expect 10 "короче теперь")
48 (ert-info ("Message well within `erc-split-line-length'")
49 (erc-scenarios-common-say
50 (concat
51 "короче теперь если по русски написать все четко или все равно"
52 " короче теперь если по русски написать все четко или все равно"
53 " короче теперь если по русски написать все четко или все равно"
54 " короче теперь если по русски написать все четко или все равно"))
55 (funcall expect 1 "<tester>")
56 (funcall expect -0.1 "<tester>"))
57
58 (ert-info ("Message over `erc-split-line-length'")
59 (erc-scenarios-common-say
60 (concat
61 "короче теперь если по русски написать все четко или все равно"
62 " короче теперь если по русски написать все четко или все равно"
63 " короче теперь если по русски написать все четко или все равно"
64 " короче теперь если по русски написать все четко или все равно"
65 " короче теперь если по русски написать все четко или все равно"
66 " короче теперь если по русски написать все четко или все равно"
67 " короче теперь если по русски написать все четко или все равно"
68 " будет разрыв строки непонятно где"))
69 (funcall expect 1 "<tester>")
70 (funcall expect 1 "<tester> разрыв")))
71
72 (with-current-buffer "foonet"
73 (erc-cmd-QUIT "")
74 (funcall expect 10 "finished"))))
75
76(ert-deftest erc-scenarios-base-split-line--ascii ()
77 :tags '(:expensive-test)
78 (should (equal erc-split-line-length 440))
79 (erc-scenarios-common-with-cleanup
80 ((erc-scenarios-common-dialog "base/flood")
81 (msg-432 (string-join (make-list 18 "twenty-three characters") " "))
82 (erc-server-flood-penalty 0.1)
83 (dumb-server (erc-d-run "localhost" t 'ascii))
84 (port (process-contact dumb-server :service))
85 (expect (erc-d-t-make-expecter)))
86
87 (ert-info ("Connect to server")
88 (with-current-buffer (erc :server "127.0.0.1"
89 :port port
90 :nick "tester"
91 :full-name "tester")
92 (funcall expect 10 "debug mode")
93 (erc-cmd-JOIN "#ascii")))
94
95 (with-current-buffer (erc-d-t-wait-for 8 (get-buffer "#ascii"))
96 (ert-info ("Message with spaces fits exactly")
97 (funcall expect 10 "Welcome")
98 (should (= (length (concat msg-432 " 12345678")) 440))
99 (erc-scenarios-common-say (concat msg-432 " 12345678"))
100 (funcall expect 1 "<tester>")
101 ;; Sent in a single go, hence no second <speaker>.
102 (funcall expect -0.1 "<tester>")
103 (funcall expect 0.1 "12345678"))
104
105 (ert-info ("Message with spaces too long.")
106 (erc-scenarios-common-say (concat msg-432 " 123456789"))
107 (funcall expect 1 "<tester>")
108 ;; Sent in two passes, split at last word.
109 (funcall expect 0.1 "<tester> 123456789"))
110
111 (ert-info ("Message sans spaces fits exactly")
112 (erc-scenarios-common-say (make-string 440 ?x))
113 (funcall expect 1 "<tester>")
114 ;; Sent in a single go, hence no second <speaker>.
115 (funcall expect -0.1 "<tester>"))
116
117 (ert-info ("Message sans spaces too long.")
118 (erc-scenarios-common-say (concat (make-string 440 ?y) "z"))
119 (funcall expect 1 "<tester>")
120 ;; Sent in two passes, split at last word.
121 (funcall expect 0.1 "<tester> z"))
122
123 (ert-info ("Rejected when escape-hatch set")
124 (let ((erc--reject-unbreakable-lines t))
125 (should-error
126 (erc-scenarios-common-say
127 (concat
128 "https://mail.example.org/verify?token="
129 (string-join (make-list 18 "twenty-three_characters") "_")))))))
130
131 (with-current-buffer "foonet"
132 (erc-cmd-QUIT "")
133 (funcall expect 10 "finished"))))
134
135(ert-deftest erc-scenarios-base-split-line--utf-8 ()
136 :tags '(:expensive-test)
137 (unless (> emacs-major-version 27)
138 (ert-skip "No emojis in Emacs 27"))
139
140 (should (equal erc-split-line-length 440))
141 (erc-scenarios-common-with-cleanup
142 ((erc-scenarios-common-dialog "base/flood")
143 (msg-432 (string-join (make-list 18 "twenty-three characters") " "))
144 (erc-server-flood-penalty 0.1)
145 (dumb-server (erc-d-run "localhost" t 'utf-8))
146 (port (process-contact dumb-server :service))
147 (expect (erc-d-t-make-expecter)))
148
149 (ert-info ("Connect to server")
150 (with-current-buffer (erc :server "127.0.0.1"
151 :port port
152 :nick "tester"
153 :full-name "tester")
154 (funcall expect 10 "debug mode")
155 (erc-cmd-JOIN "#utf-8")))
156
157 (with-current-buffer (erc-d-t-wait-for 8 (get-buffer "#utf-8"))
158 (funcall expect 10 "Welcome")
159
160 (ert-info ("Message with spaces over `erc-split-line-length'")
161 (erc-scenarios-common-say
162 (concat
163 "короче теперь если по русски написать все четко или все равно"
164 " короче теперь если по русски написать все четко или все равно"
165 " короче теперь если по русски написать все четко или все равно"
166 " короче теперь если по русски написать все четко или все равно"
167 " короче теперь если по русски написать все четко или все равно"
168 " короче теперь если по русски написать все четко или все равно"
169 " короче теперь если по русски написать все четко или все равно"
170 " будет разрыв строки непонятно где"
171 " будет разрыв строки непонятно где"))
172 (funcall expect 1 "<tester> короче")
173 (funcall expect 1 "<tester> все")
174 (funcall expect 1 "<tester> разрыв")
175 (funcall expect 1 "Entirely honour"))
176
177 (ert-info ("Message sans spaces over `erc-split-line-length'")
178 (erc-scenarios-common-say
179 (concat "話說天下大勢,分久必合,合久必分:周末七國分爭,并入於秦。"
180 "及秦滅之後,楚、漢分爭,又并入於漢。漢朝自高祖斬白蛇而起義,"
181 "一統天下。後來光武中興,傳至獻帝,遂分為三國。推其致亂之由,"
182 "殆始於桓、靈二帝。桓帝禁錮善類,崇信宦官。及桓帝崩,靈帝即位,"
183 "大將軍竇武、太傅陳蕃,共相輔佐。時有宦官曹節等弄權,竇武、陳蕃謀誅之,"
184 "作事不密,反為所害。中涓自此愈橫"))
185 (funcall expect 1 "<tester>")
186 ;; Sent in two passes, split at last word.
187 (funcall expect 0.1 "<tester> 竇武")
188 (funcall expect 1 "this prey out"))
189
190 ;; Combining emojis are respected.
191 (ert-info ("Message sans spaces over small `erc-split-line-length'")
192 (let ((erc-split-line-length 100))
193 (erc-scenarios-common-say
194 "будет разрыв строки непонятно где🏁🚩🎌🏴🏳️🏳️‍🌈🏳️‍⚧️🏴‍☠️"))
195 (funcall expect 1 "<tester>")
196 (funcall expect 1 "<tester> 🏳️‍🌈")))
197
198 (with-current-buffer "foonet"
199 (erc-cmd-QUIT "")
200 (funcall expect 10 "finished"))))
201
202;;; erc-scenarios-base-split-line.el ends here
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 4725d289e5b..b6702617aeb 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1044,6 +1044,48 @@
1044 (kill-buffer "*erc-protocol*") 1044 (kill-buffer "*erc-protocol*")
1045 (should-not erc-debug-irc-protocol))) 1045 (should-not erc-debug-irc-protocol)))
1046 1046
1047(ert-deftest erc--split-line ()
1048 (let ((erc-default-recipients '("#chan"))
1049 (erc-split-line-length 10))
1050 (should (equal (erc--split-line "") '("")))
1051 (should (equal (erc--split-line "0123456789") '("0123456789")))
1052 (should (equal (erc--split-line "0123456789a") '("0123456789" "a")))
1053
1054 (should (equal (erc--split-line "0123456789 ") '("0123456789" " ")))
1055 (should (equal (erc--split-line "01234567 89") '("01234567 " "89")))
1056 (should (equal (erc--split-line "0123456 789") '("0123456 " "789")))
1057 (should (equal (erc--split-line "0 123456789") '("0 " "123456789")))
1058 (should (equal (erc--split-line " 0123456789") '(" " "0123456789")))
1059 (should (equal (erc--split-line "012345678 9a") '("012345678 " "9a")))
1060 (should (equal (erc--split-line "0123456789 a") '("0123456789" " a")))
1061
1062 ;; UTF-8 vs. KOI-8
1063 (should (= 10 (string-bytes "Русск"))) ; utf-8
1064 (should (equal (erc--split-line "Русск") '("Русск")))
1065 (should (equal (erc--split-line "РусскийТекст") '("Русск" "ийТек" "ст")))
1066 (should (equal (erc--split-line "Русский Текст") '("Русск" "ий " "Текст")))
1067 (let ((erc-encoding-coding-alist '(("#chan" . cyrillic-koi8))))
1068 (should (equal (erc--split-line "Русск") '("Русск")))
1069 (should (equal (erc--split-line "РусскийТекст") '("РусскийТек" "ст")))
1070 (should (equal (erc--split-line "Русский Текст") '("Русский " "Текст"))))
1071
1072 ;; UTF-8 vs. Latin 1
1073 (should (= 17 (string-bytes "Hyvää päivää")))
1074 (should (equal (erc--split-line "Hyvää päivää") '("Hyvää " "päivää")))
1075 (should (equal (erc--split-line "HyvääPäivää") '("HyvääPä" "ivää")))
1076 (let ((erc-encoding-coding-alist '(("#chan" . latin-1))))
1077 (should (equal (erc--split-line "Hyvää päivää") '("Hyvää " "päivää")))
1078 (should (equal (erc--split-line "HyvääPäivää") '("HyvääPäivä" "ä"))))
1079
1080 ;; Combining characters
1081 (should (= 10 (string-bytes "Åström")))
1082 (should (equal (erc--split-line "_Åström") '("_Åströ" "m")))
1083 (should (equal (erc--split-line "__Åström") '("__Åstr" "öm")))
1084 (should (equal (erc--split-line "___Åström") '("___Åstr" "öm")))
1085 (when (> emacs-major-version 27)
1086 (should (equal (erc--split-line "🏁🚩🎌🏴🏳️🏳️‍🌈🏳️‍⚧️🏴‍☠️")
1087 '("🏁🚩" "🎌🏴" "🏳️" "🏳️‍🌈" "🏳️‍⚧️" "🏴‍☠️"))))))
1088
1047(ert-deftest erc--input-line-delim-regexp () 1089(ert-deftest erc--input-line-delim-regexp ()
1048 (let ((p erc--input-line-delim-regexp)) 1090 (let ((p erc--input-line-delim-regexp))
1049 ;; none 1091 ;; none
@@ -1181,8 +1223,9 @@
1181 (ert-info ("Input cleared") 1223 (ert-info ("Input cleared")
1182 (erc-bol) 1224 (erc-bol)
1183 (should (eq (point) (point-max)))) 1225 (should (eq (point) (point-max))))
1184 ;; Commands are forced (no flood protection) 1226 ;; The `force' argument is irrelevant here because it can't
1185 (should (equal (funcall next) '("/msg #chan hi\n" t nil)))) 1227 ;; influence dispatched handlers, such as `erc-cmd-MSG'.
1228 (should (pcase (funcall next) (`("/msg #chan hi\n" ,_ nil) t))))
1186 1229
1187 (ert-info ("Simple non-command") 1230 (ert-info ("Simple non-command")
1188 (insert "hi") 1231 (insert "hi")
@@ -1190,7 +1233,8 @@
1190 (should (eq (point) (point-max))) 1233 (should (eq (point) (point-max)))
1191 (should (save-excursion (forward-line -1) 1234 (should (save-excursion (forward-line -1)
1192 (search-forward "<tester> hi"))) 1235 (search-forward "<tester> hi")))
1193 ;; Non-ommands are forced only when `erc-flood-protect' is nil 1236 ;; Non-commands are forced only when `erc-flood-protect' is
1237 ;; nil, which conflates two orthogonal concerns.
1194 (should (equal (funcall next) '("hi\n" nil t)))) 1238 (should (equal (funcall next) '("hi\n" nil t))))
1195 1239
1196 (should (consp erc-last-input-time))))) 1240 (should (consp erc-last-input-time)))))
diff --git a/test/lisp/erc/resources/base/flood/ascii.eld b/test/lisp/erc/resources/base/flood/ascii.eld
new file mode 100644
index 00000000000..a3d127326c3
--- /dev/null
+++ b/test/lisp/erc/resources/base/flood/ascii.eld
@@ -0,0 +1,49 @@
1;; -*- mode: lisp-data; -*-
2((nick 10 "NICK tester"))
3((user 10 "USER user 0 * :tester")
4 (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
5 (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
6 (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 12 Mar 2023 02:30:29 UTC")
7 (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
8 (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
9 (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
10 (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server")
11 (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
12 (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
13 (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
14 (0.00 ":irc.foonet.org 254 tester 1 :channels formed")
15 (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
16 (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
17 (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
18 (0.00 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the day - ")
19 (0.00 ":irc.foonet.org 372 tester :- This is the default Ergo MOTD.")
20 (0.01 ":irc.foonet.org 372 tester :- ")
21 (0.02 ":irc.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md")
22 (0.00 ":irc.foonet.org 376 tester :End of MOTD command"))
23
24((mode-tester 10 "MODE tester +i")
25 (0.00 ":irc.foonet.org 221 tester +i")
26 (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
27 (0.05 ":irc.foonet.org 221 tester +i"))
28
29((join-spam 10 "JOIN #ascii")
30 (0 ":tester!~u@9g6b728983yd2.irc JOIN #ascii")
31 (0 ":irc.foonet.org 353 tester = #ascii :alice tester @bob")
32 (0 ":irc.foonet.org 366 tester #ascii :End of NAMES list"))
33
34((mode-spam 10 "MODE #ascii")
35 (0 ":irc.foonet.org 324 tester #ascii +nt")
36 (0 ":irc.foonet.org 329 tester #ascii 1620104779")
37 (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #ascii :tester, welcome!")
38 (0.0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #ascii :tester, welcome!"))
39
40((privmsg 10 "PRIVMSG #ascii :twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters 12345678"))
41((privmsg 10 "PRIVMSG #ascii :twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters twenty-three characters "))
42((privmsg 10 "PRIVMSG #ascii :123456789"))
43((privmsg 10 "PRIVMSG #ascii :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))
44((privmsg 10 "PRIVMSG #ascii :yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"))
45((privmsg 10 "PRIVMSG #ascii :z"))
46
47((quit 10 "QUIT :\2ERC\2")
48 (0.07 ":tester!~u@h3f95zveyc38a.irc QUIT :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)")
49 (0.01 "ERROR :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)"))
diff --git a/test/lisp/erc/resources/base/flood/koi8-r.eld b/test/lisp/erc/resources/base/flood/koi8-r.eld
new file mode 100644
index 00000000000..0f10717fc2c
--- /dev/null
+++ b/test/lisp/erc/resources/base/flood/koi8-r.eld
@@ -0,0 +1,47 @@
1;; -*- mode: lisp-data; -*-
2((nick 10 "NICK tester"))
3((user 10 "USER user 0 * :tester")
4 (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
5 (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
6 (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 12 Mar 2023 02:30:29 UTC")
7 (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
8 (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
9 (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
10 (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server")
11 (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
12 (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
13 (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
14 (0.00 ":irc.foonet.org 254 tester 1 :channels formed")
15 (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
16 (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
17 (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
18 (0.00 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the day - ")
19 (0.00 ":irc.foonet.org 372 tester :- This is the default Ergo MOTD.")
20 (0.01 ":irc.foonet.org 372 tester :- ")
21 (0.02 ":irc.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md")
22 (0.00 ":irc.foonet.org 376 tester :End of MOTD command"))
23
24((mode-tester 10 "MODE tester +i")
25 (0.00 ":irc.foonet.org 221 tester +i")
26 (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
27 (0.05 ":irc.foonet.org 221 tester +i"))
28
29((join-chan 6 "JOIN #koi8")
30 (0 ":tester!~u@9g6b728983yd2.irc JOIN #koi8")
31 (0 ":irc.foonet.org 353 tester = #koi8 :alice tester @bob")
32 (0 ":irc.foonet.org 366 tester #koi8 :End of NAMES list"))
33
34((mode-chan 8 "MODE #koi8")
35 (0 ":irc.foonet.org 324 tester #koi8 +nt")
36 (0 ":irc.foonet.org 329 tester #koi8 1620104779")
37 (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #koi8 :tester, welcome!")
38 (0.0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #koi8 :tester, welcome!")
39 (0.0 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #koi8 :\313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317"))
40
41((privmsg 10 "PRIVMSG #koi8 :\313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317"))
42((privmsg 10 "PRIVMSG #koi8 :\313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \313\317\322\317\336\305 \324\305\320\305\322\330 \305\323\314\311 \320\317 \322\325\323\323\313\311 \316\301\320\311\323\301\324\330 \327\323\305 \336\305\324\313\317 \311\314\311 \327\323\305 \322\301\327\316\317 \302\325\304\305\324 "))
43((privmsg 10 "PRIVMSG #koi8 :\322\301\332\322\331\327 \323\324\322\317\313\311 \316\305\320\317\316\321\324\316\317 \307\304\305"))
44
45((quit 10 "QUIT :\2ERC\2")
46 (0.07 ":tester!~u@h3f95zveyc38a.irc QUIT :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)")
47 (0.01 "ERROR :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)"))
diff --git a/test/lisp/erc/resources/base/flood/utf-8.eld b/test/lisp/erc/resources/base/flood/utf-8.eld
new file mode 100644
index 00000000000..8e7f8f7eed2
--- /dev/null
+++ b/test/lisp/erc/resources/base/flood/utf-8.eld
@@ -0,0 +1,54 @@
1;; -*- mode: lisp-data; -*-
2((nick 10 "NICK tester"))
3((user 10 "USER user 0 * :tester")
4 (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
5 (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
6 (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 12 Mar 2023 02:30:29 UTC")
7 (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
8 (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
9 (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
10 (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server")
11 (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
12 (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
13 (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
14 (0.00 ":irc.foonet.org 254 tester 1 :channels formed")
15 (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
16 (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
17 (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
18 (0.00 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the day - ")
19 (0.00 ":irc.foonet.org 372 tester :- This is the default Ergo MOTD.")
20 (0.01 ":irc.foonet.org 372 tester :- ")
21 (0.02 ":irc.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md")
22 (0.00 ":irc.foonet.org 376 tester :End of MOTD command"))
23
24((mode-tester 10 "MODE tester +i")
25 (0.00 ":irc.foonet.org 221 tester +i")
26 (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
27 (0.05 ":irc.foonet.org 221 tester +i"))
28
29((join-spam 10 "JOIN #utf-8")
30 (0 ":tester!~u@9g6b728983yd2.irc JOIN #utf-8")
31 (0 ":irc.foonet.org 353 tester = #utf-8 :alice tester @bob")
32 (0 ":irc.foonet.org 366 tester #utf-8 :End of NAMES list"))
33
34((mode-spam 10 "MODE #utf-8")
35 (0 ":irc.foonet.org 324 tester #utf-8 +nt")
36 (0 ":irc.foonet.org 329 tester #utf-8 1620104779")
37 (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #utf-8 :tester, welcome!")
38 (0.0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #utf-8 :tester, welcome!"))
39
40((privmsg-a 10 "PRIVMSG #utf-8 :\320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 "))
41((privmsg-b 10 "PRIVMSG #utf-8 :\320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\272\320\276\321\200\320\276\321\207\320\265 \321\202\320\265\320\277\320\265\321\200\321\214 \320\265\321\201\320\273\320\270 \320\277\320\276 \321\200\321\203\321\201\321\201\320\272\320\270 \320\275\320\260\320\277\320\270\321\201\320\260\321\202\321\214 \320\262\321\201\320\265 \321\207\320\265\321\202\320\272\320\276 \320\270\320\273\320\270 \320\262\321\201\320\265 \321\200\320\260\320\262\320\275\320\276 \320\261\321\203\320\264\320\265\321\202 \321\200\320\260\320\267\321\200\321\213\320\262 \321\201\321\202\321\200\320\276\320\272\320\270 \320\275\320\265\320\277\320\276\320\275\321\217\321\202\320\275\320\276 \320\263\320\264\320\265 \320\261\321\203\320\264\320\265\321\202 "))
42((privmsg-c 10 "PRIVMSG #utf-8 :\321\200\320\260\320\267\321\200\321\213\320\262 \321\201\321\202\321\200\320\276\320\272\320\270 \320\275\320\265\320\277\320\276\320\275\321\217\321\202\320\275\320\276 \320\263\320\264\320\265")
43 (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #utf-8 :alice: Entirely honour; I would not be delay'd."))
44
45((privmsg-g 10 "PRIVMSG #utf-8 :\350\251\261\350\252\252\345\244\251\344\270\213\345\244\247\345\213\242\357\274\214\345\210\206\344\271\205\345\277\205\345\220\210\357\274\214\345\220\210\344\271\205\345\277\205\345\210\206\357\274\232\345\221\250\346\234\253\344\270\203\345\234\213\345\210\206\347\210\255\357\274\214\345\271\266\345\205\245\346\226\274\347\247\246\343\200\202\345\217\212\347\247\246\346\273\205\344\271\213\345\276\214\357\274\214\346\245\232\343\200\201\346\274\242\345\210\206\347\210\255\357\274\214\345\217\210\345\271\266\345\205\245\346\226\274\346\274\242\343\200\202\346\274\242\346\234\235\350\207\252\351\253\230\347\245\226\346\226\254\347\231\275\350\233\207\350\200\214\350\265\267\347\276\251\357\274\214\344\270\200\347\265\261\345\244\251\344\270\213\343\200\202\345\276\214\344\276\206\345\205\211\346\255\246\344\270\255\350\210\210\357\274\214\345\202\263\350\207\263\347\215\273\345\270\235\357\274\214\351\201\202\345\210\206\347\202\272\344\270\211\345\234\213\343\200\202\346\216\250\345\205\266\350\207\264\344\272\202\344\271\213\347\224\261\357\274\214\346\256\206\345\247\213\346\226\274\346\241\223\343\200\201\351\235\210\344\272\214\345\270\235\343\200\202\346\241\223\345\270\235\347\246\201\351\214\256\345\226\204\351\241\236\357\274\214\345\264\207\344\277\241\345\256\246\345\256\230\343\200\202\345\217\212\346\241\223\345\270\235\345\264\251\357\274\214\351\235\210\345\270\235\345\215\263\344\275\215\357\274\214\345\244\247\345\260\207\350\273\215\347\253\207\346\255\246\343\200\201\345\244\252\345\202\205\351\231\263\350\225\203\357\274\214\345\205\261\347\233\270\350\274\224\344\275\220\343\200\202\346\231\202\346\234\211\345\256\246\345\256\230\346\233\271\347\257\200\347\255\211\345\274\204\346\254\212\357\274\214"))
46((privmsg-h 10 "PRIVMSG #utf-8 :\347\253\207\346\255\246\343\200\201\351\231\263\350\225\203\350\254\200\350\252\205\344\271\213\357\274\214\344\275\234\344\272\213\344\270\215\345\257\206\357\274\214\345\217\215\347\202\272\346\211\200\345\256\263\343\200\202\344\270\255\346\266\223\350\207\252\346\255\244\346\204\210\346\251\253")
47 (0.0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #utf-8 :Shall seize this prey out of his father's hands."))
48
49((privmsg-d 10 "PRIVMSG #utf-8 :\320\261\321\203\320\264\320\265\321\202\302\240\321\200\320\260\320\267\321\200\321\213\320\262\302\240\321\201\321\202\321\200\320\276\320\272\320\270\302\240\320\275\320\265\320\277\320\276\320\275\321\217\321\202\320\275\320\276\302\240\320\263\320\264\320\265\360\237\217\201\360\237\232\251\360\237\216\214\360\237\217\264\360\237\217\263\357\270\217"))
50((privmsg-e 10 "PRIVMSG #utf-8 :\360\237\217\263\357\270\217\342\200\215\360\237\214\210\360\237\217\263\357\270\217\342\200\215\342\232\247\357\270\217\360\237\217\264\342\200\215\342\230\240\357\270\217"))
51
52((quit 10 "QUIT :\2ERC\2")
53 (0.07 ":tester!~u@h3f95zveyc38a.irc QUIT :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)")
54 (0.01 "ERROR :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)"))
diff --git a/test/lisp/erc/resources/erc-d/erc-d.el b/test/lisp/erc/resources/erc-d/erc-d.el
index 43f6552f0f3..e9d880644d4 100644
--- a/test/lisp/erc/resources/erc-d/erc-d.el
+++ b/test/lisp/erc/resources/erc-d/erc-d.el
@@ -456,7 +456,7 @@ including line delimiters."
456 (setq string (unless (= (match-end 0) (length string)) 456 (setq string (unless (= (match-end 0) (length string))
457 (substring string (match-end 0)))) 457 (substring string (match-end 0))))
458 (erc-d--log process line nil) 458 (erc-d--log process line nil)
459 (ring-insert queue (erc-d-i--parse-message line 'decode)))) 459 (ring-insert queue (erc-d-i--parse-message line nil))))
460 (when string 460 (when string
461 (setf (process-get process :stashed-input) string)))) 461 (setf (process-get process :stashed-input) string))))
462 462