emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/org dc0c60f: org-element-parse-buffer: Avoid interferen


From: ELPA Syncer
Subject: [elpa] externals/org dc0c60f: org-element-parse-buffer: Avoid interference with element cache
Date: Wed, 3 Nov 2021 07:57:24 -0400 (EDT)

branch: externals/org
commit dc0c60f123688b56d785058f63d2e57d67002191
Author: Ihor Radchenko <yantar92@gmail.com>
Commit: Ihor Radchenko <yantar92@gmail.com>

    org-element-parse-buffer: Avoid interference with element cache
    
    * lisp/org-element.el (org-element-copy): Make sure that element
    properties containing secondary objects are also copied.
    (org-element--parse-elements): Avoid modifying cached elements.
    
    Fixes 
https://list.orgmode.org/CAHyO48yS2EAJnhiYoK7syjb1_Fbfxcv2A0fk4t5RFzTLj1hSGA@mail.gmail.com/
    In the backtrace provided in the email, org-roam calls to
    `org-element-parse-buffer' add uncached `org-data' element as cached
    element `:parent' property.  Uncached elements in `:parent' property
    break the cache code.
---
 lisp/org-element.el | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/lisp/org-element.el b/lisp/org-element.el
index 9fa6fd5..a02d392 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -669,7 +669,21 @@ is cleared and contents are removed in the process."
        (`plain-text (substring-no-properties datum))
        (`nil (copy-sequence datum))
        (_
-        (list type (plist-put (copy-sequence (nth 1 datum)) :parent nil)))))))
+         (let ((element-copy (list type (plist-put (copy-sequence (nth 1 
datum)) :parent nil))))
+           ;; We cannot simply return the copies property list.  When
+           ;; DATUM is i.e. a headline, it's property list (`:title'
+           ;; in case of headline) can contain parsed objects.  The
+           ;; objects will contain `:parent' property set to the DATUM
+           ;; iteself.  When copied, these inner `:parent' propery
+           ;; values will contain incorrect object decoupled from
+           ;; DATUM.  Changes to the DATUM copy will not longer be
+           ;; reflected in the `:parent' properties.  So, we need to
+           ;; reassign inner `:parent' propreties to the DATUM copy
+           ;; explicitly.
+           (org-element-map element-copy (cons 'plain-text 
org-element-all-objects)
+             (lambda (obj) (when (equal datum (org-element-property :parent 
obj))
+                        (org-element-put-property obj :parent element-copy))))
+           element-copy))))))
 
 
 
@@ -4729,8 +4743,20 @@ Elements are accumulated into ACC."
              (when (and (eolp) (not (eobp))) (forward-char)))
          ;; Find current element's type and parse it accordingly to
          ;; its category.
-         (let* ((element (org-element--current-element
-                          end granularity mode structure))
+         (let* ((element (org-element-copy
+                           ;; `org-element--current-element' may return cached
+                           ;; elements.  Below code reassigns
+                           ;; `:parent' property of the element and
+                           ;; may interfere with cache
+                           ;; synchronisation if parent element is not
+                           ;; yet in cache.  Moreover, the returned
+                           ;; structure may be altered by caller code
+                           ;; arbitrarily.  Hence, we return a copy of
+                           ;; the potentially cached element to make
+                           ;; potential modifications safe for element
+                           ;; cache.
+                           (org-element--current-element
+                           end granularity mode structure)))
                 (type (org-element-type element))
                 (cbeg (org-element-property :contents-begin element)))
            (goto-char (org-element-property :end element))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]