Subject: bug#64089: Acknowledgement (30.0.50; `ldap-search' errors out with `wrong-type-argument listp' when called WITHDN == t)

From: Jens Schmidt <[email-masked]>
Date: Fri, 16 Jun 2023 00:11:15 +0200

With the following patch things work as expected:

(ldap-search "(uid=<uid>)"
               "ldap://<host>"
               '("mail")
               nil
               t)
=> ((("dn" "cn=<NAME>,L=<REGION>,DC=<DOMAIN>,DC=COM") ("mail" 
"<name>@<domain>.com")))

I tried to make the patch as conservative as possible and intentionally 
do not check syntax of the dn line if its parsing is not required.

From a646f5aa23f051f19910286c1bf9f4580a858f0f Mon Sep 17 00:00:00 2001
From: Jens Schmidt <[email-masked]>
Date: Fri, 16 Jun 2023 00:04:04 +0200
Subject: [PATCH] Fix parsing of dn line if WITHDN is non-nil

Function `ldap-search' errors out with `wrong-type-argument listp'
when called with WITHDN non-nil.
* lisp/net/ldap.el (ldap-search-internal): Parse the dn line
correctly so that `ldap-search' can grok it.  (Bug#64089)
---
 lisp/net/ldap.el | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el
index 78405414a28..4275b45e6f5 100644
--- a/lisp/net/ldap.el
+++ b/lisp/net/ldap.el
@@ -703,7 +703,17 @@ ldap-search-internal
 	(while (progn
 		 (skip-chars-forward " \t\n")
 		 (not (eobp)))
-          (setq dn (buffer-substring (point) (line-end-position)))
+          ;; Ignore first (dn) line if WITHDN equals nil.  If WITHDN
+          ;; is non-nil, check syntax of the line and split it into a
+          ;; pair as expected by `ldap-decode-attribute' (Bug#64089).
+          ;; If the syntax is wrong, better throw an error here, since
+          ;; otherwise `ldap-decode-attribute' would throw a much less
+          ;; comprehensible error later.
+          (cond ((not withdn))
+                ((looking-at "^dn[=:\t ]+\\(.*\\)$")
+                 (setq dn (list "dn" (match-string 1))))
+                (t (error "Incorrect dn line \"%s\" in ldapsearch result"
+                          (buffer-substring (point) (line-end-position)))))
 	  (forward-line 1)
           (while (looking-at "^\\([A-Za-z][-A-Za-z0-9]*\
 \\|[0-9]+\\(?:\\.[0-9]+\\)*\\)\\(;[-A-Za-z0-9]+\\)*[=:\t ]+\
-- 
2.30.2