unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "J.P." <jp@neverwas.me>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 46342@debbugs.gnu.org
Subject: bug#46342: 28.0.50; socks-send-command munges IP address bytes to UTF-8
Date: Sun, 07 Feb 2021 06:22:53 -0800	[thread overview]
Message-ID: <875z34vtxe.fsf@neverwas.me> (raw)
In-Reply-To: <83czxdns61.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 06 Feb 2021 17:15:50 +0200")

[-- Attachment #1: Type: text/plain, Size: 3005 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> Re appropriate encoding: correct me if I'm wrong (internet), but among
>> the Emacs coding systems, it'd be latin-1.
>
> That depends on what the other end expects.  Does it expect latin-1 in
> this case?

From the point of view of Emacs, I'd say yes: the other end, meaning the
proxy service, expects latin-1. From the service's point of view, it
only speaks byte sequences and doesn't interpret any fields as text [1].
This continues after proxying has commenced; incoming byte sequences are
forwarded verbatim as opaque payloads.

> Does emitting the single byte \330 produce the correct result in this
> case?  Then by all means please use
>
>    (encode-coding-string address 'latin-1)

It does indeed produce the correct result [2], and I've updated the
patch to reflect this. I wasn't sure whether you wanted me to replace
all the vectors in the tests with strings and/or annotate them with
comments explaining the protocol, so I just left them as is for now.

My main concern (based on sheer ignorance) was any possible side effects
that may occur from encode-coding-string setting the variable
last-coding-system-used to latin-1. I investigated a little by stepping
through the subsequent send_process() call and found that the variable's
value as latin-1 appears short lived because it's quickly reassigned to
binary. I tried to demonstrate this in the attached log of my debug
session (and also show that no conversion is performed). Please pardon
my sad debugging skills.

>> Re program on the other end: this would be any program offering a proxy
>> service that speaks the same protocol. Popular ones include tor and ssh.
>> [...]
>
> And those expect Latin-1 encoding in this case?

I'd say yes, insofar as these programs are examples of a proxy service
of the sort mentioned in the first answer above.

Thanks again


[1] Although, in the case of SOCKS 4A/5, non-numeric addresses, i.e.,
domain names, should probably be expressed in characters a resolver can
understand, like the Punycode ASCII subset.

[2] there is one tiny difference in behavior from the previous iteration
of this patch, but it's not worth anyone's time, so I'll just note it
here for the record: when called in the manner shown in the patch,
encode-coding-string silently replaces multibyte characters with spaces.

The only edge case I could think of in which accidentally passing a
multibyte might be harder to debug than a normal typo would be when
hitting an address like ec2-13-56-13-123.us-west-1.compute.amazonaws.com
and accidentally passing 13.256.13.123 (as "\15\u0100\15\173"), which
would be routed to 13.32.13.123 (flickr/cloudflare).

One way to avoid this would be with validation like that performed by
unibyte-string or, alternatively, by purposefully violating the protocol
and sending say, "\15\15{" instead of "\15 \15{" (and thereby triggering
an error response from the service). All in all, this seems unlikely
enough not to warrant special attention.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-more-auth-related-tests-for-socks.el.patch --]
[-- Type: text/x-patch, Size: 15775 bytes --]

From ef931d35a3ed345750dbf2b2553026266c81cea4 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 5 Feb 2021 05:24:55 -0800
Subject: [PATCH 1/2] Add more auth-related tests for socks.el

* test/lisp/net/socks-tests.el (auth-registration-and-suite-offer)
(filter-response-parsing-v4, filter-response-parsing-v5): Assert
auth-method selection wrangling and socks-filter parsing.
(v5-auth-user-pass, v5-auth-user-pass-blank, v5-auth-none): Show prep
and execution of the SOCKS connect command and proxying of an HTTP
request; simplify fake server.
---
 test/lisp/net/socks-tests.el | 263 +++++++++++++++++++++++++++--------
 1 file changed, 208 insertions(+), 55 deletions(-)

diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el
index b378ed2964e..d2c21094e7f 100644
--- a/test/lisp/net/socks-tests.el
+++ b/test/lisp/net/socks-tests.el
@@ -21,68 +21,149 @@
 
 ;;; Code:
 
+(require 'ert)
 (require 'socks)
 (require 'url-http)
 
-(defvar socks-tests-canned-server-port nil)
+(ert-deftest socks-tests-auth-registration-and-suite-offer ()
+  (ert-info ("Default favors user/pass auth")
+    (should (equal socks-authentication-methods
+                   '((2 "Username/Password" . socks-username/password-auth)
+                     (0 "No authentication" . identity))))
+    (should (equal "\2\0\2" (socks-build-auth-list)))) ; length [offer ...]
+  (let (socks-authentication-methods)
+    (ert-info ("Empty selection/no methods offered")
+      (should (equal "\0" (socks-build-auth-list))))
+    (ert-info ("Simulate library defaults")
+      (socks-register-authentication-method 0 "No authentication"
+                                            'identity)
+      (should (equal socks-authentication-methods
+                     '((0 "No authentication" . identity))))
+      (should (equal "\1\0" (socks-build-auth-list)))
+      (socks-register-authentication-method 2 "Username/Password"
+                                            'socks-username/password-auth)
+      (should (equal socks-authentication-methods
+                     '((2 "Username/Password" . socks-username/password-auth)
+                       (0 "No authentication" . identity))))
+      (should (equal "\2\0\2" (socks-build-auth-list))))
+    (ert-info ("Removal")
+      (socks-unregister-authentication-method 2)
+      (should (equal socks-authentication-methods
+                     '((0 "No authentication" . identity))))
+      (should (equal "\1\0" (socks-build-auth-list)))
+      (socks-unregister-authentication-method 0)
+      (should-not socks-authentication-methods)
+      (should (equal "\0" (socks-build-auth-list))))))
 
-(defun socks-tests-canned-server-create (verbatim patterns)
-  "Create a fake SOCKS server and return the process.
+(ert-deftest socks-tests-filter-response-parsing-v4 ()
+  (let* ((buf (generate-new-buffer "*test-socks-filter*"))
+         (proc (start-process "test-socks-filter" buf "sleep" "1")))
+    (process-put proc 'socks t)
+    (process-put proc 'socks-state socks-state-waiting)
+    (process-put proc 'socks-server-protocol 4)
+    (ert-info ("Receive initial incomplete segment")
+      (socks-filter proc (concat [0 90 0 0 93 184 216]))
+      ;; From example.com: OK status ^      ^ msg start
+      (ert-info ("State still set to waiting")
+        (should (eq (process-get proc 'socks-state) socks-state-waiting)))
+      (ert-info ("Response field is nil because processing incomplete")
+        (should-not (process-get proc 'socks-response)))
+      (ert-info ("Scratch field holds stashed partial payload")
+        (should (string= (concat [0 90 0 0 93 184 216])
+                         (process-get proc 'socks-scratch)))))
+    (ert-info ("Last part arrives")
+      (socks-filter proc "\42") ; ?\" 34
+      (ert-info ("State transitions to complete (length check passes)")
+        (should (eq (process-get proc 'socks-state) socks-state-connected)))
+      (ert-info ("Scratch and response fields hold stash w. last chunk")
+        (should (string= (concat [0 90 0 0 93 184 216 34])
+                         (process-get proc 'socks-response)))
+        (should (string= (process-get proc 'socks-response)
+                         (process-get proc 'socks-scratch)))))
+    (delete-process proc)
+    (kill-buffer buf)))
 
-`VERBATIM' and `PATTERNS' are dotted alists containing responses.
-Requests are tried in order.  On failure, an error is raised."
-  (let* ((buf (generate-new-buffer "*canned-socks-server*"))
+(ert-deftest socks-tests-filter-response-parsing-v5 ()
+  (let* ((buf (generate-new-buffer "*test-socks-filter*"))
+         (proc (start-process "test-socks-filter" buf "sleep" "1")))
+    (process-put proc 'socks t)
+    (process-put proc 'socks-state socks-state-waiting)
+    (process-put proc 'socks-server-protocol 5)
+    (ert-info ("Receive initial incomplete segment")
+      ;; From fedora.org: 2605:bc80:3010:600:dead:beef:cafe:fed9
+      ;; 5004 ~~> Version Status (OK) NOOP Addr-Type (4 -> IPv6)
+      (socks-filter proc "\5\0\0\4\x26\x05\xbc\x80\x30\x10\x00\x60") ; unibyte
+      (ert-info ("State still waiting and response emtpy")
+        (should (eq (process-get proc 'socks-state) socks-state-waiting))
+        (should-not (process-get proc 'socks-response)))
+      (ert-info ("Scratch field holds partial payload of pending msg")
+        (should (string= "\5\0\0\4\x26\x05\xbc\x80\x30\x10\x00\x60"
+                         (process-get proc 'socks-scratch)))))
+    (ert-info ("Middle chunk arrives")
+      (socks-filter proc "\xde\xad\xbe\xef\xca\xfe\xfe\xd9")
+      (ert-info ("State and response fields still untouched")
+        (should (eq (process-get proc 'socks-state) socks-state-waiting))
+        (should-not (process-get proc 'socks-response)))
+      (ert-info ("Scratch contains new arrival appended (on RHS)")
+        (should (string=  (concat "\5\0\0\4"
+                                  "\x26\x05\xbc\x80\x30\x10\x00\x60"
+                                  "\xde\xad\xbe\xef\xca\xfe\xfe\xd9")
+                          (process-get proc 'socks-scratch)))))
+    (ert-info ("Final part arrives (port number)")
+      (socks-filter proc "\0\0")
+      (ert-info ("State transitions to complete")
+        (should (eq (process-get proc 'socks-state) socks-state-connected)))
+      (ert-info ("Scratch and response fields show last chunk appended")
+        (should (string=  (concat "\5\0\0\4"
+                                  "\x26\x05\xbc\x80\x30\x10\x00\x60"
+                                  "\xde\xad\xbe\xef\xca\xfe\xfe\xd9"
+                                  "\0\0")
+                          (process-get proc 'socks-scratch)))
+        (should (string= (process-get proc 'socks-response)
+                         (process-get proc 'socks-scratch)))))
+    (delete-process proc)
+    (kill-buffer buf)))
+
+(defvar socks-tests-canned-server-patterns nil
+  "Alist containing request/response cons pairs to be tried in order.
+Vectors must match verbatim. Strings are considered regex patterns.")
+
+(defun socks-tests-canned-server-create ()
+  "Create and return a fake SOCKS server."
+  (let* ((port (nth 2 socks-server))
+         (name (format "socks-server:%d" port))
+         (pats socks-tests-canned-server-patterns)
          (filt (lambda (proc line)
-                 (let ((resp (or (assoc-default line verbatim
-                                                (lambda (k s) ; s is line
-                                                  (string= (concat k) s)))
-                                 (assoc-default line patterns
-                                                (lambda (p s)
-                                                  (string-match-p p s))))))
-                   (unless resp
+                 (pcase-let ((`(,pat . ,resp) (pop pats)))
+                   (unless (or (and (vectorp pat) (equal pat (vconcat line)))
+                               (string-match-p pat line))
                      (error "Unknown request: %s" line))
                    (let ((print-escape-control-characters t))
-                     (princ (format "<- %s\n" (prin1-to-string line)) buf)
-                     (princ (format "-> %s\n" (prin1-to-string resp)) buf))
+                     (message "[%s] <- %s" name (prin1-to-string line))
+                     (message "[%s] -> %s" name (prin1-to-string resp)))
                    (process-send-string proc (concat resp)))))
-         (srv (make-network-process :server 1
-                                    :buffer buf
-                                    :filter filt
-                                    :name "server"
-                                    :family 'ipv4
-                                    :host 'local
-                                    :service socks-tests-canned-server-port)))
-    (set-process-query-on-exit-flag srv nil)
-    (princ (format "[%s] Listening on localhost:10080\n" srv) buf)
-    srv))
-
-;; Add ([5 3 0 1 2] . [5 2]) to the `verbatim' list below to validate
-;; against curl 7.71 with the following options:
-;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com
-;;
-;; If later implementing version 4a, try these:
-;; [4 1 0 80 0 0 0 1 0 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0] . [0 90 0 0 0 0 0 0]
-;; $ curl --verbose --proxy socks4a://127.0.0.1:10080 example.com
+         (serv (make-network-process :server 1
+                                     :buffer (get-buffer-create name)
+                                     :filter filt
+                                     :name name
+                                     :family 'ipv4
+                                     :host 'local
+                                     :coding 'binary
+                                     :service port)))
+    (set-process-query-on-exit-flag serv nil)
+    serv))
 
-(ert-deftest socks-tests-auth-filter-url-http ()
-  "Verify correct handling of SOCKS5 user/pass authentication."
-  (let* ((socks-server '("server" "127.0.0.1" 10080 5))
-         (socks-username "foo")
-         (socks-password "bar")
-         (url-gateway-method 'socks)
+(defvar socks-tests--hello-world-http-request-pattern
+  (cons "^GET /" (concat "HTTP/1.1 200 OK\r\n"
+                         "Content-Type: text/plain\r\n"
+                         "Content-Length: 13\r\n\r\n"
+                         "Hello World!\n")))
+
+(defun socks-tests-perform-hello-world-http-request ()
+  "Start canned server, validate hello-world response, and finalize."
+  (let* ((url-gateway-method 'socks)
          (url (url-generic-parse-url "http://example.com"))
-         (verbatim '(([5 2 0 2] . [5 2])
-                     ([1 3 ?f ?o ?o 3 ?b ?a ?r] . [1 0])
-                     ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80]
-                      . [5 0 0 1 0 0 0 0 0 0])))
-         (patterns
-          `(("^GET /" . ,(concat "HTTP/1.1 200 OK\r\n"
-                                 "Content-Type: text/plain; charset=UTF-8\r\n"
-                                 "Content-Length: 13\r\n\r\n"
-                                 "Hello World!\n"))))
-         (socks-tests-canned-server-port 10080)
-         (server (socks-tests-canned-server-create verbatim patterns))
-         (tries 10)
+         (server (socks-tests-canned-server-create))
          ;;
          done
          ;;
@@ -90,14 +171,86 @@ socks-tests-auth-filter-url-http
                (goto-char (point-min))
                (should (search-forward "Hello World" nil t))
                (setq done t)))
-         (buf (url-http url cb '(nil))))
-    (ert-info ("Connect to HTTP endpoint over SOCKS5 with USER/PASS method")
-      (while (and (not done) (< 0 (cl-decf tries))) ; cl-lib via url-http
-        (sleep-for 0.1)))
+         (buf (url-http url cb '(nil)))
+         (proc (get-buffer-process buf))
+         (attempts 10))
+    (while (and (not done) (< 0 (cl-decf attempts)))
+      (sleep-for 0.1))
     (should done)
     (delete-process server)
+    (delete-process proc) ; otherwise seems client proc is sometimes reused
     (kill-buffer (process-buffer server))
     (kill-buffer buf)
     (ignore url-gateway-method)))
 
+;; Replace first pattern below with ([5 3 0 1 2] . [5 2]) to validate
+;; against curl 7.71 with the following options:
+;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com
+
+(ert-deftest socks-tests-v5-auth-user-pass ()
+  "Verify correct handling of SOCKS5 user/pass authentication."
+  (should (assq 2 socks-authentication-methods))
+  (let ((socks-server '("server" "127.0.0.1" 10080 5))
+        (socks-username "foo")
+        (socks-password "bar")
+        (url-user-agent "Test/auth-user-pass")
+        (socks-tests-canned-server-patterns
+         `(([5 2 0 2] . [5 2])
+           ([1 3 ?f ?o ?o 3 ?b ?a ?r] . [1 0])
+           ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80]
+            . [5 0 0 1 0 0 0 0 0 0])
+           ,socks-tests--hello-world-http-request-pattern)))
+    (ert-info ("Make HTTP request over SOCKS5 with USER/PASS auth method")
+      (socks-tests-perform-hello-world-http-request))))
+
+;; Services (like Tor) may be configured without auth but for some
+;; reason still prefer the user/pass method over none when offered both.
+;; Given this library's defaults, the scenario below is possible.
+;;
+;; FYI: RFC 1929 doesn't say that a username or password is required
+;; but notes that the length of both fields should be at least one.
+;; However, both socks.el and curl send zero-length fields (though
+;; curl drops the user part too when the password is empty).
+;;
+;; To verify against curl 7.71, swap out the first two pattern pairs
+;; with ([5 3 0 1 2] . [5 2]) and ([1 0 0] . [1 0]), then run:
+;; $ curl verbose -U "foo:" --proxy socks5h://127.0.0.1:10081 example.com
+
+(ert-deftest socks-tests-v5-auth-user-pass-blank ()
+  "Verify correct SOCKS5 user/pass authentication with empty pass."
+  (should (assq 2 socks-authentication-methods))
+  (let ((socks-server '("server" "127.0.0.1" 10081 5))
+        (socks-username "foo") ; defaults to (user-login-name)
+        (socks-password "") ; simulate user hitting enter when prompted
+        (url-user-agent "Test/auth-user-pass-blank")
+        (socks-tests-canned-server-patterns
+         `(([5 2 0 2] . [5 2])
+           ([1 3 ?f ?o ?o 0] . [1 0])
+           ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80]
+            . [5 0 0 1 0 0 0 0 0 0])
+           ,socks-tests--hello-world-http-request-pattern)))
+    (ert-info ("Make HTTP request over SOCKS5 with USER/PASS auth method")
+      (socks-tests-perform-hello-world-http-request))))
+
+;; Swap out ([5 2 0 1] . [5 0]) with the first pattern below to validate
+;; against curl 7.71 with the following options:
+;; $ curl --verbose --proxy socks5h://127.0.0.1:10082 example.com
+
+(ert-deftest socks-tests-v5-auth-none ()
+  "Verify correct handling of SOCKS5 when auth method 0 requested."
+  (let ((socks-server '("server" "127.0.0.1" 10082 5))
+        (socks-authentication-methods (append socks-authentication-methods
+                                              nil))
+        (url-user-agent "Test/auth-none")
+        (socks-tests-canned-server-patterns
+         `(([5 1 0] . [5 0])
+           ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80]
+            . [5 0 0 1 0 0 0 0 0 0])
+           ,socks-tests--hello-world-http-request-pattern)))
+    (socks-unregister-authentication-method 2)
+    (should-not (assq 2 socks-authentication-methods))
+    (ert-info ("Make HTTP request over SOCKS5 with no auth method")
+      (socks-tests-perform-hello-world-http-request)))
+  (should (assq 2 socks-authentication-methods)))
+
 ;;; socks-tests.el ends here
-- 
2.29.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Preserve-numeric-addresses-in-socks-send-command.patch --]
[-- Type: text/x-patch, Size: 2346 bytes --]

From 96018fe24dbab8c1f0dbf31c120a088f1998519f Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 5 Feb 2021 19:41:04 -0800
Subject: [PATCH 2/2] Preserve numeric addresses in socks-send-command

* lisp/net/socks.el: (socks-send-command):
* test/lisp/net/socks-tests.el: (socks-tests-v4-basic):
---
 lisp/net/socks.el            |  2 +-
 test/lisp/net/socks-tests.el | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/lisp/net/socks.el b/lisp/net/socks.el
index 96fafc826b8..019fadd1440 100644
--- a/lisp/net/socks.el
+++ b/lisp/net/socks.el
@@ -393,7 +393,7 @@ socks-send-command
   (let ((addr (cond
 	       ((or (= atype socks-address-type-v4)
 		    (= atype socks-address-type-v6))
-		address)
+		(encode-coding-string address 'latin-1))
 	       ((= atype socks-address-type-name)
 		(format "%c%s" (length address) address))
 	       (t
diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el
index d2c21094e7f..7112f42a67c 100644
--- a/test/lisp/net/socks-tests.el
+++ b/test/lisp/net/socks-tests.el
@@ -183,6 +183,26 @@ socks-tests-perform-hello-world-http-request
     (kill-buffer buf)
     (ignore url-gateway-method)))
 
+;; Unlike curl, socks.el includes the ID field (but otherwise matches):
+;; $ curl --proxy socks4://127.0.0.1:1080 example.com
+
+(ert-deftest socks-tests-v4-basic ()
+  "Show correct preparation of SOCKS4 connect command."
+  (let ((socks-server '("server" "127.0.0.1" 10079 4))
+        (url-user-agent "Test/4-basic")
+        (socks-tests-canned-server-patterns
+         `(([4 1 0 80 93 184 216 34 ?f ?o ?o 0] . [0 90 0 0 0 0 0 0])
+           ,socks-tests--hello-world-http-request-pattern))
+        socks-nslookup-program)
+    (ert-info ("Make HTTP request over SOCKS4")
+      (cl-letf (((symbol-function 'socks-nslookup-host)
+                 (lambda (host)
+                   (should (equal host "example.com"))
+                   (list 93 184 216 34)))
+                ((symbol-function 'user-full-name)
+                 (lambda () "foo")))
+        (socks-tests-perform-hello-world-http-request)))))
+
 ;; Replace first pattern below with ([5 3 0 1 2] . [5 2]) to validate
 ;; against curl 7.71 with the following options:
 ;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com
-- 
2.29.2


[-- Attachment #4: debug_session.log --]
[-- Type: text/plain, Size: 11758 bytes --]

// session 2
HEAD is 06e1e5eeacf67b11490431c3d36700a73cf49d88
Dmitry Gutov <dgutov@yandex.ru> Revert "Fix the previous change"
// note: I broke a few long lines

Current directory: /home/jp/emacs/test/
Command: gdb
set annotate 1
set filename-display absolute
GNU gdb (GDB) Fedora 10.1-2.fc33
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
.gdbinit:19: Error in sourced command file:
No symbol table is loaded.  Use the "file" command.
gdb$ file ../src/emacs
Reading symbols from ../src/emacs...
gdb$ source .gdbinit
DISPLAY = :1
TERM = xterm-256color
Breakpoint 1 at 0x420251: file /home/jp/emacs/src/emacs.c, line 379.
Breakpoint 2 at 0x4d9080: file /home/jp/emacs/src/xterm.c, line 10181.
gdb$ break /home/jp/emacs/src/process.c:6357
Breakpoint 3 at 0x5c9d5f: file /home/jp/emacs/src/process.c, line 6359.
gdb$ set args --module-assertions --no-init-file --no-site-file --no-site-lisp \
-L :. -l ert -l lisp/net/socks-tests.el --batch \
--eval \(ert-run-tests-batch-and-exit\ \(quote\ socks-tests-v4-basic\)\)
gdb$ run
Starting program: /home/jp/emacs/src/emacs \
--module-assertions --no-init-file --no-site-file --no-site-lisp \
-L :. -l ert -l lisp/net/socks-tests.el --batch \
--eval \(ert-run-tests-batch-and-exit\ \(quote\ socks-tests-v4-basic\)\)
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.32-4.fc33.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7fffe63e1640 (LWP 386228)]
Running 1 tests (2021-02-07 05:12:37-0800, selector ‘socks-tests-v4-basic’)
Contacting host: example.com:80

Thread 1 "emacs" hit Breakpoint 3, send_process (proc=XIL(0xc18ed5), buf=0xc17f20 "\004\001", len=12,
    object=XIL(0xdb1964)) at /home/jp/emacs/src/process.c:6359
  /home/jp/emacs/src/process.c:6359:187302:beg:0x5c9d5f
gdb$ p *p
$1 = {
  header = {
    size = 4611686018561691669
  },
  tty_name = XIL(0),
  name = XIL(0xb80044),
  command = XIL(0),
  filter = XIL(0x14d410),
  sentinel = XIL(0x83d0),
  log = XIL(0),
  buffer = XIL(0),
  childp = XIL(0xdad983),
  plist = XIL(0xdada43),
  type = XIL(0xa4d0),
  mark = XIL(0xce7ee5),
  status = XIL(0xbf70),
  decode_coding_system = XIL(0x7ffff3bb1388),
  decoding_buf = XIL(0x7ffff422f424),
  encode_coding_system = XIL(0x7ffff3bb1388),
  encoding_buf = XIL(0x7ffff422f424),
  write_queue = XIL(0),
  gnutls_cred_type = XIL(0),
  gnutls_boot_parameters = XIL(0),
  stderrproc = XIL(0),
  thread = XIL(0x9bc6c5),
--Type <RET> for more, q to quit, c to continue without paging--c
  pid = 0,
  infd = 7,
  nbytes_read = 0,
  outfd = 7,
  open_fd = {7, -1, -1, -1, -1, -1},
  tick = 0,
  update_tick = 0,
  decoding_carryover = 0,
  read_output_delay = 0,
  adaptive_read_buffering = 0,
  read_output_skip = false,
  kill_without_query = true,
  pty_flag = false,
  inherit_coding_system_flag = false,
  alive = false,
  raw_status_new = false,
  is_non_blocking_client = false,
  is_server = false,
  raw_status = 0,
  backlog = 5,
  port = 0,
  socktype = 1,
  dns_request = 0x0,
  gnutls_initstage = GNUTLS_STAGE_EMPTY,
  gnutls_state = 0x0,
  gnutls_x509_cred = 0x0,
  gnutls_anon_cred = 0x0,
  gnutls_certificates = 0x0,
  gnutls_certificates_length = 0,
  gnutls_peer_verification = 0,
  gnutls_extra_peer_verification = 0,
  gnutls_log_level = 0,
  gnutls_handshakes_tried = 0,
  gnutls_p = false,
  gnutls_complete_negotiation_p = false
}
gdb$ p p->decode_coding_system
$2 = XIL(0x7ffff3bb1388)
gdb$ pr
binary
gdb$ p p->encode_coding_system
$3 = XIL(0x7ffff3bb1388)
gdb$ pr
binary
gdb$ print Vlast_coding_system_used
$4 = XIL(0x8df0)
gdb$ pr
latin-1
gdb$ n
  /home/jp/emacs/src/process.c:6360:187338:beg:0x5c9d64
gdb$
  /home/jp/emacs/src/process.c:6363:187384:beg:0x5c976c
gdb$
  /home/jp/emacs/src/lisp.h:718:25723:beg:0x5c977e
gdb$
  /home/jp/emacs/src/process.c:6367:187517:beg:0x5c978a
gdb$
  /home/jp/emacs/src/process.c:6371:187644:beg:0x5c9799
gdb$
  /home/jp/emacs/src/process.c:6372:187692:beg:0x5c97a1
gdb$ p *coding
$5 = {
  id = 5,
  common_flags = 256,
  mode = 0,
  src_multibyte = true,
  dst_multibyte = true,
  chars_at_source = false,
  raw_destination = false,
  annotated = true,
  eol_seen = 5,
  result = 6,
  max_charset_id = 0,
  spec = {
    iso_2022 = {
      flags = 14359680,
      current_invocation = {0, 14359680},
      current_designation = {0, 0, 0, 0},
      ctext_extended_segment_len = 0,
      single_shifting = false,
      bol = false,
      embedded_utf_8 = false,
      cmp_status = {
        state = COMPOSING_NO,
        method = COMPOSITION_RELATIVE,
        old_form = false,
--Type <RET> for more, q to quit, c to continue without paging--c
        length = 0,
        nchars = 0,
        ncomps = 0,
        carryover = {0 <repeats 68 times>}
      }
    },
    ccl = 0xdb1c80,
    utf_16 = {
      bom = (unknown: 0xdb1c80),
      endian = utf_16_big_endian,
      surrogate = 14359680
    },
    utf_8_bom = (unknown: 0xdb1c80),
    emacs_mule = {
      cmp_status = {
        state = 14359680,
        method = COMPOSITION_RELATIVE,
        old_form = 128,
        length = 0,
        nchars = 0,
        ncomps = 0,
        carryover = {0 <repeats 68 times>}
      }
    },
    undecided = {
      inhibit_nbd = 14359680,
      inhibit_ied = 0,
      prefer_utf_8 = 128
    }
  },
  safe_charsets = 0x7ffff49f7257 "\377",
  head_ascii = 0,
  detected_utf8_bytes = 0,
  detected_utf8_chars = 0,
  produced = 0,
  produced_char = 0,
  consumed = 0,
  consumed_char = 0,
  src_pos = 0,
  src_pos_byte = 0,
  src_chars = 0,
  src_bytes = 0,
  src_object = XIL(0),
  source = 0x0,
  dst_pos = 0,
  dst_pos_byte = 0,
  dst_bytes = 0,
  dst_object = XIL(0),
  destination = 0x0,
  charbuf = 0x0,
  charbuf_size = 0,
  charbuf_used = 0,
  carryover = '\000' <repeats 63 times>,
  carryover_bytes = 0,
  default_char = 0,
  detector = 0x0,
  decoder = 0x499df0 <decode_coding_raw_text>,
  encoder = 0x49efe0 <encode_coding_raw_text>
}
gdb$ l
6367	  if (p->outfd < 0)
6368	    error ("Output file descriptor of %s is closed", SDATA (p->name));
6369
6370	  eassert (p->outfd < FD_SETSIZE);
6371	  coding = proc_encode_coding_system[p->outfd];
6372	  Vlast_coding_system_used = CODING_ID_NAME (coding->id);
6373
6374	  if ((STRINGP (object) && STRING_MULTIBYTE (object))
6375	      || (BUFFERP (object)
6376		  && !NILP (BVAR (XBUFFER (object), enable_multibyte_characters)))
gdb$ fr
Stack level 0, frame at 0x7fffffff9080:
 rip = 0x5c97a1 in send_process (/home/jp/emacs/src/process.c:6372);
    saved rip = 0x5c9f74
 called by frame at 0x7fffffff9090
 source language c.
 Arglist at 0x7fffffff9008, args: proc=XIL(0xc18ed5), buf=0xc17f20 "\004\001", len=12,
    object=XIL(0xdb1964)
 Locals at 0x7fffffff9008, Previous frame's sp is 0x7fffffff9080
 Saved registers:
  rbx at 0x7fffffff9048, rbp at 0x7fffffff9050, r12 at 0x7fffffff9058, r13 at 0x7fffffff9060,
  r14 at 0x7fffffff9068, r15 at 0x7fffffff9070, rip at 0x7fffffff9078
proc = XIL(0xc18ed5)
buf = 0xc17f20 "\004\001"
len = 12
object = XIL(0xdb1964)
p = 0xc18ed0
rv = <optimized out>
coding = 0xdb1c90
gdb$ n
  /home/jp/emacs/src/process.c:6374:187751:beg:0x5c97b7
gdb$
  /home/jp/emacs/src/lisp.h:718:25723:beg:0x5c97c4
gdb$
  /home/jp/emacs/src/lisp.h:730:25858:beg:0x5c97ce
gdb$
  /home/jp/emacs/src/process.c:6375:187805:beg:0x5c9b1a
gdb$
  /home/jp/emacs/src/lisp.h:718:25723:beg:0x5c9b27
gdb$
  /home/jp/emacs/src/process.c:6398:188683:beg:0x5c9b31
gdb$
  /home/jp/emacs/src/process.c:6402:188909:beg:0x5c9b41
gdb$
  /home/jp/emacs/src/process.c:6417:189358:beg:0x5c9800
gdb$
  /home/jp/emacs/src/process.c:6419:189388:beg:0x5c9808
gdb$ p *coding
$6 = {
  id = 5,
  common_flags = 256,
  mode = 0,
  src_multibyte = false,
  dst_multibyte = false,
  chars_at_source = false,
  raw_destination = false,
  annotated = true,
  eol_seen = 5,
  result = 6,
  max_charset_id = 0,
  spec = {
    iso_2022 = {
      flags = 14359680,
      current_invocation = {0, 14359680},
      current_designation = {0, 0, 0, 0},
      ctext_extended_segment_len = 0,
      single_shifting = false,
      bol = false,
      embedded_utf_8 = false,
      cmp_status = {
        state = COMPOSING_NO,
        method = COMPOSITION_RELATIVE,
        old_form = false,
--Type <RET> for more, q to quit, c to continue without paging--c
        length = 0,
        nchars = 0,
        ncomps = 0,
        carryover = {0 <repeats 68 times>}
      }
    },
    ccl = 0xdb1c80,
    utf_16 = {
      bom = (unknown: 0xdb1c80),
      endian = utf_16_big_endian,
      surrogate = 14359680
    },
    utf_8_bom = (unknown: 0xdb1c80),
    emacs_mule = {
      cmp_status = {
        state = 14359680,
        method = COMPOSITION_RELATIVE,
        old_form = 128,
        length = 0,
        nchars = 0,
        ncomps = 0,
        carryover = {0 <repeats 68 times>}
      }
    },
    undecided = {
      inhibit_nbd = 14359680,
      inhibit_ied = 0,
      prefer_utf_8 = 128
    }
  },
  safe_charsets = 0x7ffff49f7257 "\377",
  head_ascii = 0,
  detected_utf8_bytes = 0,
  detected_utf8_chars = 0,
  produced = 0,
  produced_char = 0,
  consumed = 0,
  consumed_char = 0,
  src_pos = 0,
  src_pos_byte = 0,
  src_chars = 0,
  src_bytes = 0,
  src_object = XIL(0),
  source = 0x0,
  dst_pos = 0,
  dst_pos_byte = 0,
  dst_bytes = 0,
  dst_object = XIL(0),
  destination = 0x0,
  charbuf = 0x0,
  charbuf_size = 0,
  charbuf_used = 0,
  carryover = '\000' <repeats 63 times>,
  carryover_bytes = 0,
  default_char = 0,
  detector = 0x0,
  decoder = 0x499df0 <decode_coding_raw_text>,
  encoder = 0x49efe0 <encode_coding_raw_text>
}
gdb$ print Vlast_coding_system_used
$7 = XIL(0x7ffff3bb1388)
gdb$ pr
binary
gdb$ p object
$8 = XIL(0xdb1964)
gdb$ pr
"^D^A^@P]\270\330\"foo^@"
gdb$ xstring object
$9 = (struct Lisp_String *) 0xdb1960
"\004\001\000P]\270\330\"foo"
gdb$ p *$9
$10 = {
  u = {
    s = {
      size = 12,
      size_byte = -1,
      intervals = 0x0,
      data = 0xc17f20 "\004\001"
    },
    next = 0xc,
    gcaligned = 12 '\f'
  }
}
gdb$ del 3
gdb$ c
Continuing.
[socks-server:10079] <- "\4\1\0P]\270\330\"foo\0"
[socks-server:10079] -> [0 90 0 0 0 0 0 0]
[socks-server:10079] <- "GET / HTTP/1.1\15\12MIME-Version: 1.0\15\12Connection: keep-alive\15\12Extension: Security/Digest Security/SSL\15\12Host: example.com\15\12Accept-encoding: gzip\15\12Accept: */*\15\12User-Agent: Test/4-basic\15\12\15\12"
[socks-server:10079] -> "HTTP/1.1 200 OK\15\12Content-Type: text/plain\15\12Content-Length: 13\15\12\15\12Hello World!\12"
   passed  1/1  socks-tests-v4-basic (951.587240 sec)

Ran 1 tests, 1 results as expected, 0 unexpected (2021-02-07 05:28:28-0800, 951.587586 sec)

[Thread 0x7fffe63e1640 (LWP 386228) exited]
[Inferior 1 (process 386123) exited normally]

  reply	other threads:[~2021-02-07 14:22 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-06 11:46 bug#46342: 28.0.50; socks-send-command munges IP address bytes to UTF-8 J.P.
2021-02-06 12:26 ` Eli Zaretskii
2021-02-06 14:19   ` J.P.
2021-02-06 15:15     ` Eli Zaretskii
2021-02-07 14:22       ` J.P. [this message]
2021-02-09 15:17       ` J.P.
2021-02-09 16:14         ` Eli Zaretskii
2021-02-10 13:16           ` J.P.
2021-02-10 16:04             ` Eli Zaretskii
2021-02-11 14:58               ` J.P.
2021-02-11 15:28                 ` Eli Zaretskii
2021-02-12 14:30                   ` J.P.
2021-02-12 15:04                     ` Eli Zaretskii
2021-02-13 15:43                       ` J.P.
2021-02-17 14:59                       ` J.P.
2021-02-20  9:33                         ` Eli Zaretskii
2021-02-20 10:13                           ` J.P.
2021-02-20 11:08                             ` Eli Zaretskii
2021-02-20 15:08                               ` J.P.
2021-02-20 15:19                                 ` Eli Zaretskii
2021-02-20 10:41                           ` J.P.

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=875z34vtxe.fsf@neverwas.me \
    --to=jp@neverwas.me \
    --cc=46342@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).