diff options
| author | Eli Zaretskii | 2018-08-02 16:29:54 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2018-08-02 16:29:54 +0300 |
| commit | 7669bf7880e54aae7036a1b62db3693c2f627649 (patch) | |
| tree | 7501dc2012f50662e6b0e508872b9446d549fcf3 /src/textprop.c | |
| parent | 15458a8301c41214609348a7476a6c0c639a89b6 (diff) | |
| download | emacs-7669bf7880e54aae7036a1b62db3693c2f627649.tar.gz emacs-7669bf7880e54aae7036a1b62db3693c2f627649.zip | |
Avoid assertion violations in set_text_properties_1
* src/textprop.c (set_text_properties): If the call to
modify_text_properties modifies the interval tree as side effect,
recalculate the correct interval for START and END. (Bug#32265)
Diffstat (limited to 'src/textprop.c')
| -rw-r--r-- | src/textprop.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/textprop.c b/src/textprop.c index 984f2e66406..904e2265bdb 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -1350,6 +1350,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1350 | { | 1350 | { |
| 1351 | register INTERVAL i; | 1351 | register INTERVAL i; |
| 1352 | Lisp_Object ostart, oend; | 1352 | Lisp_Object ostart, oend; |
| 1353 | bool first_time = true; | ||
| 1353 | 1354 | ||
| 1354 | ostart = start; | 1355 | ostart = start; |
| 1355 | oend = end; | 1356 | oend = end; |
| @@ -1372,6 +1373,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1372 | return Qt; | 1373 | return Qt; |
| 1373 | } | 1374 | } |
| 1374 | 1375 | ||
| 1376 | retry: | ||
| 1375 | i = validate_interval_range (object, &start, &end, soft); | 1377 | i = validate_interval_range (object, &start, &end, soft); |
| 1376 | 1378 | ||
| 1377 | if (!i) | 1379 | if (!i) |
| @@ -1391,8 +1393,22 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1391 | return Qnil; | 1393 | return Qnil; |
| 1392 | } | 1394 | } |
| 1393 | 1395 | ||
| 1394 | if (BUFFERP (object) && !NILP (coherent_change_p)) | 1396 | if (BUFFERP (object) && !NILP (coherent_change_p) && first_time) |
| 1395 | modify_text_properties (object, start, end); | 1397 | { |
| 1398 | ptrdiff_t prev_length = LENGTH (i); | ||
| 1399 | ptrdiff_t prev_pos = i->position; | ||
| 1400 | |||
| 1401 | modify_text_properties (object, start, end); | ||
| 1402 | /* If someone called us recursively as a side effect of | ||
| 1403 | modify_text_properties, and changed the intervals behind our | ||
| 1404 | back, we cannot continue with I, because its data changed. | ||
| 1405 | So we restart the interval analysis anew. */ | ||
| 1406 | if (LENGTH (i) != prev_length || i->position != prev_pos) | ||
| 1407 | { | ||
| 1408 | first_time = false; | ||
| 1409 | goto retry; | ||
| 1410 | } | ||
| 1411 | } | ||
| 1396 | 1412 | ||
| 1397 | set_text_properties_1 (start, end, properties, object, i); | 1413 | set_text_properties_1 (start, end, properties, object, i); |
| 1398 | 1414 | ||