From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#44173: 28.0.50; gdb-mi mangles strings with octal escapes Date: Sat, 24 Oct 2020 18:21:53 +0200 Message-ID: <9D6D4CDF-DCEE-4EED-B0E5-44A999CD4DFA@acm.org> References: <2A87D378-9FB9-4FC7-951E-5BA9832051CF@acm.org> <837drhjglr.fsf@gnu.org> <834kmljd01.fsf@gnu.org> <2C183F78-8E7D-48AE-BCC2-1E32EC0A4E29@acm.org> <83zh4dhui0.fsf@gnu.org> <865DFE77-16F6-4F20-8238-76E6A09801C8@acm.org> <83mu0ciz3a.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.17\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_CF4DD323-DE40-4752-9858-14D1A017C92D" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="12402"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 44173@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Oct 24 18:23:15 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kWMK2-00036k-VV for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 24 Oct 2020 18:23:15 +0200 Original-Received: from localhost ([::1]:33688 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kWMK2-0004ZT-1l for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 24 Oct 2020 12:23:14 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:54264) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kWMJr-0004YC-59 for bug-gnu-emacs@gnu.org; Sat, 24 Oct 2020 12:23:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:51653) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kWMJq-0000IE-RP for bug-gnu-emacs@gnu.org; Sat, 24 Oct 2020 12:23:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kWMJq-0003iH-OL for bug-gnu-emacs@gnu.org; Sat, 24 Oct 2020 12:23:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 24 Oct 2020 16:23:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 44173 X-GNU-PR-Package: emacs Original-Received: via spool by 44173-submit@debbugs.gnu.org id=B44173.160355652514159 (code B ref 44173); Sat, 24 Oct 2020 16:23:02 +0000 Original-Received: (at 44173) by debbugs.gnu.org; 24 Oct 2020 16:22:05 +0000 Original-Received: from localhost ([127.0.0.1]:34947 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kWMIv-0003gJ-Fc for submit@debbugs.gnu.org; Sat, 24 Oct 2020 12:22:05 -0400 Original-Received: from mail1435c50.megamailservers.eu ([91.136.14.35]:41706 helo=mail263c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kWMIs-0003fg-Ly for 44173@debbugs.gnu.org; Sat, 24 Oct 2020 12:22:03 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1603556516; bh=Y9YIJlylEH0+yO5foN7RnnB5DGLoAqll+IBfitlu0ys=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=a6yGv+4nYydyLrpttrmvyioXbPJ9CW6R44fMlP7O1tvC2gSqToCnBjvbN8atpGmTg Oma4PiFlwUPAoUz+grBzcTWyx79ZmoAa4HW89+vDSqWe8/Yqw+5ybihvSJSvnZcX5o LMVpMwvZFO6s2FCZq7zSeL2zFY85Q/LxexEd/FhA= Feedback-ID: mattiase@acm.or Original-Received: from stanniol.lan (c-304ee655.032-75-73746f71.bbcust.telenor.se [85.230.78.48]) (authenticated bits=0) by mail263c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 09OGLrwo013832; Sat, 24 Oct 2020 16:21:55 +0000 In-Reply-To: <83mu0ciz3a.fsf@gnu.org> X-Mailer: Apple Mail (2.3445.104.17) X-CTCH-RefID: str=0001.0A782F1A.5F9454A4.000C:SCFSTAT76743386, ss=1, re=-4.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: -4.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=e6d4tph/ c=1 sm=1 tr=0 a=63Z2wlQ1NB3xHpgKFKE71g==:117 a=63Z2wlQ1NB3xHpgKFKE71g==:17 a=M51BFTxLslgA:10 a=mDV3o1hIAAAA:8 a=0vIXtaScyy5i44ZiIu0A:9 a=CjuIK1q_8ugA:10 a=47JzH84rEA7rK7q0I68A:9 a=De_Ol2h6w80A:10 a=_FVE-zBwftR9WsbkzFJk:22 X-Origin-Country: SE X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:191434 Archived-At: --Apple-Mail=_CF4DD323-DE40-4752-9858-14D1A017C92D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 23 okt. 2020 kl. 20.20 skrev Eli Zaretskii : > I don't understand your answers and don't see how they > resolve the issues I raised. Sorry if I've been communicating badly (but it takes two to do it). I honestly thought I did address your concerns but must have = misunderstood you. Please tell me what you believe I have not explained properly, and I = promise I'll do my best to answer it without referring to any previous = message. Meanwhile, here is a proof of concept which may clarify what I failed to = put in words. It actually runs both the old and new value parsers on = data sent by GDB, and logs an error message if discrepancies are found. = They seem to work identically unless there are strings with octal = escapes, which are handled correctly by the new parser. (Of course, a = proper patch would not retain the old parser.) If gdb-mi-decode-strings is non-nil, then file names, string contents = etc are properly decoded as UTF-8 as expected, without any of the = bugginess of the current code. Otherwise raw bytes are shown as octal = escapes, which also fixes the original bug. --Apple-Mail=_CF4DD323-DE40-4752-9858-14D1A017C92D Content-Disposition: attachment; filename=gdb-mi.diff Content-Type: application/octet-stream; x-unix-mode=0644; name="gdb-mi.diff" Content-Transfer-Encoding: 7bit diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 9e8af84a60..867e13b38a 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -2516,8 +2516,9 @@ gud-gdbmi-marker-filter "Filter GDB/MI output." ;; If required, decode non-ASCII text encoded with octal escapes. - (or (null gdb-mi-decode-strings) - (setq string (gdb-mi-decode string))) +;; FIXME: Now done in gdb-mi--parse-c-string; this can go away +;; (or (null gdb-mi-decode-strings) +;; (setq string (gdb-mi-decode string))) ;; Record transactions if logging is enabled. (when gdb-enable-debug @@ -2833,7 +2834,7 @@ gdb-jsonify-buffer (goto-char (point-max)) (insert "}"))) -(defun gdb-json-read-buffer (&optional fix-key fix-list) +(defun gdb-json-read-buffer-old (&optional fix-key fix-list) "Prepare and parse GDB/MI output in current buffer with `json-read'. FIX-KEY and FIX-LIST work as in `gdb-jsonify-buffer'." @@ -2843,6 +2844,140 @@ gdb-json-read-buffer (let ((json-array-type 'list)) (json-read)))) +;; Parse result records: this process converts key=value to the cons pair +;; (variable . value) where variable is a symbol. Lists and tuples become +;; Lisp lists. + +(defun gdb-mi--parse-tuple-or-list (end-char) + "Parse a GDB/MI tuple or list, both returned as a Lisp list. +END-CHAR is the ending delimiter; will stop at end-of-buffer otherwise." + (let ((items nil)) + (while (not (or (eobp) + (eq (following-char) end-char))) + (let ((item (gdb-mi--parse-result-or-value))) + (push item items) + (when (eq (following-char) ?,) + (forward-char)))) + (when (eq (following-char) end-char) + (forward-char)) + (nreverse items))) + +(defun gdb-mi--parse-c-string () + (let ((start (point)) + (pieces nil) + (octals-used nil)) + (while (and (re-search-forward (rx (or ?\\ ?\"))) + (not (eq (preceding-char) ?\"))) + (push (buffer-substring start (1- (point))) pieces) + (cond + ((looking-at (rx (** 1 3 (any "0-7")))) ;FIXME: optimise + (push (unibyte-string (string-to-number (match-string 0) 8)) pieces) + (setq octals-used t) + (goto-char (match-end 0))) + ((looking-at (rx (any "ntrvfab\"\\"))) + (push (cdr (assq (following-char) + '((?n . "\n") + (?t . "\t") + (?r . "\r") + (?v . "\v") + (?f . "\f") + (?a . "\a") + (?b . "\b") + (?\" . "\"") + (?\\ . "\\")))) + pieces) + (forward-char)) + (t + (error "Unrecognised escape char: %c" (following-char)))) + (setq start (point))) + (push (buffer-substring start (1- (point))) pieces) + (let ((s (apply #'concat (nreverse pieces)))) + (if (and octals-used gdb-mi-decode-strings) + (let ((coding + (if (coding-system-p gdb-mi-decode-strings) + gdb-mi-decode-strings + ;; FIXME: try making this cheaper + (buffer-local-value + 'buffer-file-coding-system + (gdb-get-buffer-create 'gdb-partial-output-buffer))))) + (decode-coding-string s coding)) + s)))) + +(defun gdb-mi--parse-value () + "Parse a value." + (cond + ((eq (following-char) ?\{) + (forward-char) + (gdb-mi--parse-tuple-or-list ?\})) + ((eq (following-char) ?\[) + (forward-char) + (gdb-mi--parse-tuple-or-list ?\])) + ((eq (following-char) ?\") + (forward-char) + (gdb-mi--parse-c-string)) + (t (error "Bad start of result or value: %c" (following-char))))) + +(defun gdb-mi--parse-result-or-value () + "Parse a result (key=value) or value." + (if (looking-at (rx (group (+ (any "a-zA-Z" ?_ ?-))) "=")) + (progn + (goto-char (match-end 0)) + (let* ((variable (intern (match-string 1))) + (value (gdb-mi--parse-value))) + (cons variable value))) + (gdb-mi--parse-value))) + +(defun gdb-mi--parse-results () + "Parse zero or more result productions as a list." + (gdb-mi--parse-tuple-or-list nil)) + +(defun gdb-mi--fix-key (key value) + "Convert any result (key-value pair) in VALUE whose key is KEY to its value." + (cond + ((atom value) value) + ((symbolp (car value)) + (if (eq (car value) key) + (cdr value) + (cons (car value) (gdb-mi--fix-key key (cdr value))))) + (t (mapcar (lambda (x) (gdb-mi--fix-key key x)) value)))) + +(defun gdb-mi--extend-fullname (remote value) + "Prepend REMOTE to any result string with `fullname' as the key." + (cond + ((atom value) value) + ((symbolp (car value)) + (if (and (eq (car value) 'fullname) + (stringp (cdr value))) + (cons 'fullname (concat remote (cdr value))) + (cons (car value) (gdb-mi--extend-fullname remote (cdr value))))) + (t (mapcar (lambda (x) (gdb-mi--extend-fullname remote x)) value)))) + +(defun gdb-json-read-buffer-new (&optional fix-key _fix-list) + (goto-char (point-min)) + (let ((results (gdb-mi--parse-results))) + (let ((remote (file-remote-p default-directory))) + (when remote + (setq results (gdb-mi--extend-fullname remote results)))) + (when fix-key + ;; FIXME: fix-key should be a symbol. + (setq results (gdb-mi--fix-key (intern fix-key) results))) + ;; FIXME: fix-list is irrelevant since tuples and lists in the + ;; input both yield Lisp lists. + results)) + +(defun gdb-json-read-buffer (&optional fix-key fix-list) + (save-excursion + (let* ((input (buffer-string)) + (new (gdb-json-read-buffer-new fix-key fix-list)) + (_ (cl-assert (equal (buffer-string) input))) + (old (gdb-json-read-buffer-old fix-key fix-list))) + (unless (equal old new) + (message "ERROR: input=%S" input) + (message "OLD: %S" old) + (message "NEW: %S" new)) + new))) + + (defun gdb-json-string (string &optional fix-key fix-list) "Prepare and parse STRING containing GDB/MI output with `json-read'. --Apple-Mail=_CF4DD323-DE40-4752-9858-14D1A017C92D--