Browse Source

org-element: Fix parsing radio links

* lisp/org-element.el (org-element--object-lex): Do not re-match past
  1-character long radio links.
* testing/lisp/test-org-element.el (test-org-element/link-parser): Add
  test.

Reported-by: Daniel Clemente <n142857@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/109861>
Nicolas Goaziou 8 years ago
parent
commit
a300f362a0
2 changed files with 26 additions and 7 deletions
  1. 20 7
      lisp/org-element.el
  2. 6 0
      testing/lisp/test-org-element.el

+ 20 - 7
lisp/org-element.el

@@ -4354,13 +4354,26 @@ RESTRICTION is a list of object types, as symbols, that should be
 looked after.  This function assumes that the buffer is narrowed
 looked after.  This function assumes that the buffer is narrowed
 to an appropriate container (e.g., a paragraph)."
 to an appropriate container (e.g., a paragraph)."
   (if (memq 'table-cell restriction) (org-element-table-cell-parser)
   (if (memq 'table-cell restriction) (org-element-table-cell-parser)
-    (save-excursion
-      (let ((limit (and org-target-link-regexp
-			(save-excursion
-			  (or (bolp) (backward-char))
-			  (re-search-forward org-target-link-regexp nil t))
-			(match-beginning 1)))
-	    found)
+    (let* ((start (point))
+	   (limit
+	    (save-excursion
+	      (cond ((not org-target-link-regexp) nil)
+		    ((progn
+		       (unless (bolp) (forward-char -1))
+		       (not (re-search-forward org-target-link-regexp nil t)))
+		     nil)
+		    ;; Since we moved backward, we do not want to
+		    ;; match again an hypothetical 1-character long
+		    ;; radio link before us.  Realizing that this can
+		    ;; only happen if such a radio link starts at
+		    ;; beginning of line, we prevent this here.
+		    ((and (= start (1+ (line-beginning-position)))
+			  (= start (match-end 1)))
+		     (and (re-search-forward org-target-link-regexp nil t)
+			  (match-beginning 1)))
+		    (t (match-beginning 1)))))
+	   found)
+      (save-excursion
 	(while (and (not found)
 	(while (and (not found)
 		    (re-search-forward org-element--object-regexp limit t))
 		    (re-search-forward org-element--object-regexp limit t))
 	  (goto-char (match-beginning 0))
 	  (goto-char (match-beginning 0))

+ 6 - 0
testing/lisp/test-org-element.el

@@ -1601,6 +1601,12 @@ e^{i\\pi}+1=0
       (org-element-property
       (org-element-property
        :type
        :type
        (org-element-map (org-element-parse-buffer) 'link #'identity nil t)))))
        (org-element-map (org-element-parse-buffer) 'link #'identity nil t)))))
+  ;; Pathological case: radio target of length 1 at beginning of line
+  ;; not followed by spaces.
+  (should
+   (org-test-with-temp-text "* <<<a>>>\n<point>a-bug"
+     (org-update-radio-target-regexp)
+     (org-element-parse-buffer)))
   ;; Standard link.
   ;; Standard link.
   ;;
   ;;
   ;; ... with description.
   ;; ... with description.