aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2025-03-13 22:19:14 +0200
committerEli Zaretskii2025-03-13 22:19:14 +0200
commit89441e12e2a25d43d1d5567ac356a7ecb8193063 (patch)
tree918ea1bd34ab0ecce2f0e971de63ddda180493b4 /src
parent59a67dcde4ecf8b8c346164f2d2cf90905762350 (diff)
downloademacs-89441e12e2a25d43d1d5567ac356a7ecb8193063.tar.gz
emacs-89441e12e2a25d43d1d5567ac356a7ecb8193063.zip
Fix aborts and text corruption in 'replace-buffer-contents'
* src/insdel.c (replace_range): Fix a thinko. Fix commentary. (Bug#76997)
Diffstat (limited to 'src')
-rw-r--r--src/insdel.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 3707342d2c4..9b770725971 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1409,7 +1409,11 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte,
1409 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte); 1409 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1410} 1410}
1411 1411
1412/* Replace the text from character positions FROM to TO with NEW, 1412/* Replace the text from character positions FROM to TO with NEW.
1413 NEW could either be a string, the replacement text, or a vector
1414 [BUFFER BEG END], where BUFFER is the buffer with the replacement
1415 text and BEG and END are buffer positions in BUFFER that give the
1416 replacement text beginning and end.
1413 If PREPARE, call prepare_to_modify_buffer. 1417 If PREPARE, call prepare_to_modify_buffer.
1414 If INHERIT, the newly inserted text should inherit text properties 1418 If INHERIT, the newly inserted text should inherit text properties
1415 from the surrounding non-deleted text. 1419 from the surrounding non-deleted text.
@@ -1419,9 +1423,7 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte,
1419/* Note that this does not yet handle markers quite right. 1423/* Note that this does not yet handle markers quite right.
1420 Also it needs to record a single undo-entry that does a replacement 1424 Also it needs to record a single undo-entry that does a replacement
1421 rather than a separate delete and insert. 1425 rather than a separate delete and insert.
1422 That way, undo will also handle markers properly. 1426 That way, undo will also handle markers properly. */
1423
1424 But if MARKERS is 0, don't relocate markers. */
1425 1427
1426void 1428void
1427replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, 1429replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
@@ -1504,9 +1506,19 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
1504 insend_bytes = insend; 1506 insend_bytes = insend;
1505 } 1507 }
1506 insbytes = insend_bytes - insbeg_bytes; 1508 insbytes = insend_bytes - insbeg_bytes;
1509 /* Move gap out of the replacement text, to arrange for
1510 replacement text to be contiguous in the source buffer, so that
1511 we could copy it in one go. */
1507 if (insbuf->text->gpt_byte > insbeg_bytes 1512 if (insbuf->text->gpt_byte > insbeg_bytes
1508 && insbuf->text->gpt_byte < insend_bytes) 1513 && insbuf->text->gpt_byte < insend_bytes)
1509 move_gap_both (insbeg, insbeg_bytes); 1514 {
1515 struct buffer *old = current_buffer;
1516 if (insbuf != old)
1517 set_buffer_internal (insbuf);
1518 move_gap_both (insbeg, insbeg_bytes);
1519 if (insbuf != old)
1520 set_buffer_internal (old);
1521 }
1510 insbeg_ptr = BUF_BYTE_ADDRESS (insbuf, insbeg_bytes); 1522 insbeg_ptr = BUF_BYTE_ADDRESS (insbuf, insbeg_bytes);
1511 eassert (insbuf->text->gpt_byte <= insbeg_bytes 1523 eassert (insbuf->text->gpt_byte <= insbeg_bytes
1512 || insbuf->text->gpt_byte >= insend_bytes); 1524 || insbuf->text->gpt_byte >= insend_bytes);