aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-10-30 14:17:40 -0700
committerPaul Eggert2019-10-30 14:43:14 -0700
commit40ae02ff50a8f05660a7f9f234320875b6358c9d (patch)
treec5d4a135409445f1886cda3001bfa41472f8b3fb /src
parent94b8153eaa78e376e6ed8c2b04602edf3dadc007 (diff)
downloademacs-40ae02ff50a8f05660a7f9f234320875b6358c9d.tar.gz
emacs-40ae02ff50a8f05660a7f9f234320875b6358c9d.zip
Fix fileio.c infloops on circular lists
Fix infinite loops in fileio.c when a circular list is the value of after_insert_file_functions, buffer-auto-save-file-format, buffer-file-format, or write-region-annotate-functions. * src/fileio.c (Finsert_file_contents, build_annotations): Use FOR_EACH_TAIL to avoid infloop on circular lists. (build_annotations): Use an EMACS_INT, not an int, to count nesting level. * test/src/fileio-tests.el: (fileio-tests--circular-after-insert-file-functions): New test.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/src/fileio.c b/src/fileio.c
index f1860e8a930..a3121a26dad 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4742,7 +4742,7 @@ by calling `format-decode', which see. */)
4742 /* For consistency with format-decode call these now iff inserted > 0 4742 /* For consistency with format-decode call these now iff inserted > 0
4743 (martin 2007-06-28). */ 4743 (martin 2007-06-28). */
4744 p = Vafter_insert_file_functions; 4744 p = Vafter_insert_file_functions;
4745 while (CONSP (p)) 4745 FOR_EACH_TAIL (p)
4746 { 4746 {
4747 if (NILP (replace)) 4747 if (NILP (replace))
4748 { 4748 {
@@ -4782,9 +4782,6 @@ by calling `format-decode', which see. */)
4782 inserted = XFIXNAT (insval); 4782 inserted = XFIXNAT (insval);
4783 } 4783 }
4784 } 4784 }
4785
4786 maybe_quit ();
4787 p = XCDR (p);
4788 } 4785 }
4789 4786
4790 if (!empty_undo_list_p) 4787 if (!empty_undo_list_p)
@@ -5375,14 +5372,14 @@ build_annotations (Lisp_Object start, Lisp_Object end)
5375 Lisp_Object annotations; 5372 Lisp_Object annotations;
5376 Lisp_Object p, res; 5373 Lisp_Object p, res;
5377 Lisp_Object original_buffer; 5374 Lisp_Object original_buffer;
5378 int i;
5379 bool used_global = false; 5375 bool used_global = false;
5380 5376
5381 XSETBUFFER (original_buffer, current_buffer); 5377 XSETBUFFER (original_buffer, current_buffer);
5382 5378
5383 annotations = Qnil; 5379 annotations = Qnil;
5384 p = Vwrite_region_annotate_functions; 5380 p = Vwrite_region_annotate_functions;
5385 while (CONSP (p)) 5381 loop_over_p:
5382 FOR_EACH_TAIL (p)
5386 { 5383 {
5387 struct buffer *given_buffer = current_buffer; 5384 struct buffer *given_buffer = current_buffer;
5388 if (EQ (Qt, XCAR (p)) && !used_global) 5385 if (EQ (Qt, XCAR (p)) && !used_global)
@@ -5391,7 +5388,7 @@ build_annotations (Lisp_Object start, Lisp_Object end)
5391 p = CALLN (Fappend, 5388 p = CALLN (Fappend,
5392 Fdefault_value (Qwrite_region_annotate_functions), 5389 Fdefault_value (Qwrite_region_annotate_functions),
5393 XCDR (p)); 5390 XCDR (p));
5394 continue; 5391 goto loop_over_p;
5395 } 5392 }
5396 Vwrite_region_annotations_so_far = annotations; 5393 Vwrite_region_annotations_so_far = annotations;
5397 res = call2 (XCAR (p), start, end); 5394 res = call2 (XCAR (p), start, end);
@@ -5411,7 +5408,6 @@ build_annotations (Lisp_Object start, Lisp_Object end)
5411 } 5408 }
5412 Flength (res); /* Check basic validity of return value */ 5409 Flength (res); /* Check basic validity of return value */
5413 annotations = merge (annotations, res, Qcar_less_than_car); 5410 annotations = merge (annotations, res, Qcar_less_than_car);
5414 p = XCDR (p);
5415 } 5411 }
5416 5412
5417 /* Now do the same for annotation functions implied by the file-format */ 5413 /* Now do the same for annotation functions implied by the file-format */
@@ -5419,7 +5415,8 @@ build_annotations (Lisp_Object start, Lisp_Object end)
5419 p = BVAR (current_buffer, auto_save_file_format); 5415 p = BVAR (current_buffer, auto_save_file_format);
5420 else 5416 else
5421 p = BVAR (current_buffer, file_format); 5417 p = BVAR (current_buffer, file_format);
5422 for (i = 0; CONSP (p); p = XCDR (p), ++i) 5418 EMACS_INT i = 0;
5419 FOR_EACH_TAIL (p)
5423 { 5420 {
5424 struct buffer *given_buffer = current_buffer; 5421 struct buffer *given_buffer = current_buffer;
5425 5422
@@ -5429,7 +5426,7 @@ build_annotations (Lisp_Object start, Lisp_Object end)
5429 has written annotations to a temporary buffer, which is now 5426 has written annotations to a temporary buffer, which is now
5430 current. */ 5427 current. */
5431 res = call5 (Qformat_annotate_function, XCAR (p), start, end, 5428 res = call5 (Qformat_annotate_function, XCAR (p), start, end,
5432 original_buffer, make_fixnum (i)); 5429 original_buffer, make_fixnum (i++));
5433 if (current_buffer != given_buffer) 5430 if (current_buffer != given_buffer)
5434 { 5431 {
5435 XSETFASTINT (start, BEGV); 5432 XSETFASTINT (start, BEGV);