org-persist: Fix cached data being modified by reference
* lisp/org-persist.el (org-persist--write-cache): * lisp/org-persist.el (org-persist-read): (org-persist-write): Remove `org-persist--write-cache'. The values, after reading, might sometimes be modified in place. The modifications, when done inside some kind of deeply nested structure, will propagate to the cache, polluting what was originally written in the persist file. This was a difficult bug to spot - the modification hapenned when an Org buffer was saved to a different file (C-x C-w), modified, leading to `org-element--cache' modification, and then closed. This modification propagated to `org-persist--write-cache', leading to incorrect cache value being assigned to the original buffer (before C-x C-w). Reported-by: Gregor Zattler <telegraph@gmx.net>
This commit is contained in:
parent
d33940f6e2
commit
eb6d70f817
|
@ -1006,10 +1006,6 @@ the CONTAINER as well."
|
|||
(remove container (plist-get collection :container)))
|
||||
(org-persist--add-to-index collection))))))
|
||||
|
||||
(defvar org-persist--write-cache (make-hash-table :test #'equal)
|
||||
"Hash table storing as-written data objects.
|
||||
|
||||
This data is used to avoid reading the data multiple times.")
|
||||
(cl-defun org-persist-read (container &optional associated hash-must-match load &key read-related)
|
||||
"Restore CONTAINER data for ASSOCIATED.
|
||||
When HASH-MUST-MATCH is non-nil, do not restore data if hash for
|
||||
|
@ -1057,8 +1053,7 @@ CONTAINER as well. For example:
|
|||
(unless (seq-find (lambda (v)
|
||||
(run-hook-with-args-until-success 'org-persist-before-read-hook v associated))
|
||||
(plist-get collection :container))
|
||||
(setq data (or (gethash persist-file org-persist--write-cache)
|
||||
(org-persist--read-elisp-file persist-file)))
|
||||
(setq data (org-persist--read-elisp-file persist-file))
|
||||
(when data
|
||||
(cl-loop for c in (plist-get collection :container)
|
||||
with result = nil
|
||||
|
@ -1129,7 +1124,6 @@ When IGNORE-RETURN is non-nil, just return t on success without calling
|
|||
(let ((file (org-file-name-concat org-persist-directory (plist-get collection :persist-file)))
|
||||
(data (mapcar (lambda (c) (cons c (org-persist-write:generic c collection)))
|
||||
(plist-get collection :container))))
|
||||
(puthash file data org-persist--write-cache)
|
||||
(org-persist--write-elisp-file file data)
|
||||
(or ignore-return (org-persist-read container associated)))))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue