diff options
| author | Eli Zaretskii | 2025-03-13 22:19:14 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2025-03-13 22:19:14 +0200 |
| commit | 89441e12e2a25d43d1d5567ac356a7ecb8193063 (patch) | |
| tree | 918ea1bd34ab0ecce2f0e971de63ddda180493b4 /src | |
| parent | 59a67dcde4ecf8b8c346164f2d2cf90905762350 (diff) | |
| download | emacs-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.c | 22 |
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 | ||
| 1426 | void | 1428 | void |
| 1427 | replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, | 1429 | replace_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); |