Hi all,
I found that the two functions `TeX-delete-dups-by-car' and
`TeX-delete-duplicate-strings' can fall into infinite loop under certain
contition.
I'm proposing a fix, so please tell me if someone finds any problems in
it.
[How to confirm]
1. Activate AUCTeX.
2. Evaluate (TeX-delete-duplicate-strings '("nil")) or
(TeX-delete-dups-by-car '(("nil" . 1))) . Both examples fall into
infinite loops.
[Analysis]
Since (string= "nil" nil) returns t, the loop
(while (string= elt (cadr new))
(setcdr new (cddr new)))
in `TeX-delete-duplicate-strings' never finishes when the list given as
the argument to the function ends with a string "nil" after sort.
Essentially the same reason applies for `TeX-delete-dups-by-car', too.
I estimate that it is quite uncommon that this bug causes a problem in
practical cases considering the ways that these functions are used, but
I still think it should be fixed.
[Possible fix]
The attached patch fixes the problem. Although it may seem complicated,
the essential part is just the two occurence of
- (while new
+ (while (cdr new)
only. The rest are just plain rewrite using utility functions to reduce
code duplication. (The reason that I moved the position of defun of
`TeX-car-string-lessp' is that the defcustom of `TeX-engine' requires
`TeX-delete-dups-by-car' at load time. Thus all the functions used in
`TeX-delete-dups-by-car' must be defined before the defcustom.)
Any comments and suggestions are welcome.
Regards,
Ikumi Keita
diff -r 29cedaaa8cbd tex.el
--- a/tex.el Thu Aug 31 23:39:35 2017 +0900
+++ b/tex.el Fri Sep 01 16:55:26 2017 +0900
@@ -914,12 +914,11 @@
"Return a list of all elements in ALIST, but each car only once.
Elements of KEEP-LIST are not removed even if duplicate."
;; Copy of `reftex-uniquify-by-car' (written by David Kastrup).
- (setq keep-list (sort (copy-sequence keep-list) #'string<))
+ (setq keep-list (TeX-sort-strings keep-list))
(setq alist (sort (copy-sequence alist)
- (lambda (a b)
- (string< (car a) (car b)))))
+ #'TeX-car-string-lessp))
(let ((new alist) elt)
- (while new
+ (while (cdr new)
(setq elt (caar new))
(while (and keep-list (string< (car keep-list) elt))
(setq keep-list (cdr keep-list)))
@@ -933,7 +932,7 @@
"Return a list of all strings in LIST, but each only once."
(setq list (TeX-sort-strings list))
(let ((new list) elt)
- (while new
+ (while (cdr new)
(setq elt (car new))
(while (string= elt (cadr new))
(setcdr new (cddr new)))
@@ -944,6 +943,11 @@
"Return sorted list of all strings in LIST."
(sort (copy-sequence list) #'string<))
+(defun TeX-car-string-lessp (s1 s2)
+ "Compare the cars of S1 and S2 in lexicographic order.
+Return t if first is less than second in lexicographic order."
+ (string-lessp (car s1) (car s2)))
+
;;; Buffer
(defgroup TeX-output nil
@@ -4737,11 +4741,6 @@
;; Some of these functions has little to do with TeX, but nonetheless we
;; should use the "TeX-" prefix to avoid name clashes.
-(defun TeX-car-string-lessp (s1 s2)
- "Compare the cars of S1 and S2 in lexicographic order.
-Return t if first is less than second in lexicographic order."
- (string-lessp (car s1) (car s2)))
-
(defun TeX-listify (elt)
"Return a newly created list with element ELT.
If ELT already is a list, return ELT."
_______________________________________________
auctex-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/auctex-devel