Skip to content

Commit

Permalink
Protect breakpoint persistence from print-* vars (#792)
Browse files Browse the repository at this point in the history
* Protect breakpoint persistence from print-* vars

The output of printing functions (including 'prin1' and, by
extension, 'format' with a '%s' sequence) is affected by a set of
output variables that both end-users and libraries can tweak.

This is fine in the more common use of these functions to format
messages, but the problem is that the same functions are also the
most convenient way to serialize/persist data.

Serialization should be robust to non-default values of
'print-length' and 'print-level' in particular, as setting these to
small numbers can lead to accidental data loss (and in some cases
unreadable output).

Starting in Emacs 29, 'prin1' and co. gained a new optional argument
precisely to protect against this problem.  In the meantime, this
patch ensures that 'print-length' and 'print-level' are set to their
default values during serialization.

* Minor printing simplifications

'dap--persist': 'with-temp-file' creates a fresh buffer that is
already empty, so there is no need to erase it again.  Print
data-to-persist directly to output buffer, avoiding roundtrip via
temporary string.

'dap--print-to-output-buffer': modes are enabled with a 'nil' or
nonnegative numeric argument rather than with 't'; using
'turn-on-font-lock' avoids both this pitfall, as well as redundantly
reenabling the mode.  Use an 'inhibit-read-only' binding for
temporary read-only overrides, as modifications to
'buffer-read-only' will not be undone in case of a non-local exit.

'dap-debug-edit-template': Avoid temporary string roundtrip when
checking for an empty buffer.  Use 'insert-char' for repetitions of
the same character.  Remove redundant 'prin1-to-string' in arguments
to 'format'; it already uses 'prin1' for the '%s' sequence.
  • Loading branch information
basil-conto authored May 14, 2024
1 parent 45f6a6f commit 11431a2
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions dap-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,11 @@ This is in contrast to merely setting it to 0."
"Failed to persist file: %S"
(make-directory (file-name-directory file) t)
(with-temp-file file
(erase-buffer)
(insert (prin1-to-string to-persist)))))
;; Starting with Emacs 29, `prin1' takes an optional third argument
;; which removes the need for these default bindings.
(let ((print-length nil)
(print-level nil))
(prin1 to-persist (current-buffer))))))

(defun dap--set-sessions (debug-sessions)
"Update list of debug sessions for WORKSPACE to DEBUG-SESSIONS."
Expand Down Expand Up @@ -917,14 +920,13 @@ an OUTPUT-BODY."
(defun dap--print-to-output-buffer (debug-session str)
"Insert content from STR into the output buffer associated with DEBUG-SESSION."
(with-current-buffer (get-buffer-create (dap--debug-session-output-buffer debug-session))
(font-lock-mode t)
(setq-local buffer-read-only nil)
(if (and (eq (current-buffer) (window-buffer (selected-window)))
(not (= (point) (point-max))))
(save-excursion
(dap--insert-at-point-max str))
(dap--insert-at-point-max str))
(setq-local buffer-read-only t))
(turn-on-font-lock)
(let ((inhibit-read-only t))
(if (and (eq (current-buffer) (window-buffer))
(not (eobp)))
(save-excursion
(dap--insert-at-point-max str))
(dap--insert-at-point-max str))))
(when (and dap-auto-show-output
(not (dap--debug-session-output-displayed debug-session)))
(setf (dap--debug-session-output-displayed debug-session) t)
Expand Down Expand Up @@ -1913,7 +1915,7 @@ the new template can be used normally with `dap-debug'"
(emacs-lisp-mode)
(current-buffer)))
(goto-char (point-max))
(when (s-blank? (buffer-string))
(when (bobp) ;; Empty (accessible portion of) buffer.
(insert ";; Eval Buffer with `M-x eval-buffer' to register the newly created template."))
(insert
(format "\n\n(dap-register-debug-template\n \"%s%s\"\n"
Expand All @@ -1922,13 +1924,12 @@ the new template can be used normally with `dap-debug'"
(insert " (list ")
(-let ((column (current-column))
((fst snd . rst) debug-args))
(insert (format "%s %s" fst (prin1-to-string snd)))
(insert (format "%s %s" fst snd))
(cl-loop for (k v) on rst by #'cddr
do (if (not (equal k :program-to-start))
(progn
(insert "\n")
(--dotimes column (insert " "))
(insert (format "%s %s" k (prin1-to-string v)))))))
do (unless (eq k :program-to-start)
(insert "\n")
(insert-char ?\s column)
(insert (format "%s %s" k v)))))
(insert "))"))
(pop-to-buffer "*DAP Templates*")
(goto-char (point-max)))
Expand Down

0 comments on commit 11431a2

Please sign in to comment.