emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r111875: Fix bug #13743 with crashes


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r111875: Fix bug #13743 with crashes due to recursive add-text-properties.
Date: Mon, 25 Feb 2013 18:13:42 +0200
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 111875
fixes bug: http://debbugs.gnu.org/13743
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Mon 2013-02-25 18:13:42 +0200
message:
  Fix bug #13743 with crashes due to recursive add-text-properties.
  
   src/textprop.c (Fadd_text_properties, Fremove_text_properties)
   (Fremove_list_of_text_properties): Skip all of the intervals in
   the region between START and END that already have resp. don't
   have the requested properties, not just the first one.  Add
   assertions that the loop afterwards always modifies the
   properties.
modified:
  src/ChangeLog
  src/textprop.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-02-25 16:05:49 +0000
+++ b/src/ChangeLog     2013-02-25 16:13:42 +0000
@@ -1,3 +1,12 @@
+2013-02-25  Eli Zaretskii  <address@hidden>
+
+       * textprop.c (Fadd_text_properties, Fremove_text_properties)
+       (Fremove_list_of_text_properties): Skip all of the intervals in
+       the region between START and END that already have resp. don't
+       have the requested properties, not just the first one.  Add
+       assertions that the loop afterwards always modifies the
+       properties.  (Bug#13743)
+
 2013-02-25  Stefan Monnier  <address@hidden>
 
        * callint.c (Fcall_interactively): Use the right lexical environment

=== modified file 'src/textprop.c'
--- a/src/textprop.c    2013-01-02 16:13:04 +0000
+++ b/src/textprop.c    2013-02-25 16:13:42 +0000
@@ -1133,6 +1133,7 @@
   register ptrdiff_t s, len;
   register int modified = 0;
   struct gcpro gcpro1;
+  ptrdiff_t got;
 
   properties = validate_plist (properties);
   if (NILP (properties))
@@ -1152,26 +1153,25 @@
      and live buffers are always protected.  */
   GCPRO1 (properties);
 
-  /* If we're not starting on an interval boundary, we have to
-    split this interval.  */
-  if (i->position != s)
-    {
-      /* If this interval already has the properties, we can
-         skip it.  */
-      if (interval_has_all_properties (properties, i))
-       {
-         ptrdiff_t got = (LENGTH (i) - (s - i->position));
-         if (got >= len)
-           RETURN_UNGCPRO (Qnil);
-         len -= got;
-         i = next_interval (i);
-       }
-      else
-       {
-         unchanged = i;
-         i = split_interval_right (unchanged, s - unchanged->position);
-         copy_properties (unchanged, i);
-       }
+  /* If this interval already has the properties, we can skip it.  */
+  if (interval_has_all_properties (properties, i))
+    {
+      got = LENGTH (i) - (s - i->position);
+      do {
+       if (got >= len)
+         RETURN_UNGCPRO (Qnil);
+       len -= got;
+       i = next_interval (i);
+       got = LENGTH (i);
+      } while (interval_has_all_properties (properties, i));
+    }
+  else if (i->position != s)
+    {
+      /* If we're not starting on an interval boundary, we have to
+        split this interval.  */
+      unchanged = i;
+      i = split_interval_right (unchanged, s - unchanged->position);
+      copy_properties (unchanged, i);
     }
 
   if (BUFFERP (object))
@@ -1195,7 +1195,8 @@
                signal_after_change (XINT (start), XINT (end) - XINT (start),
                                     XINT (end) - XINT (start));
 
-             return modified ? Qt : Qnil;
+             eassert (modified);
+             return Qt;
            }
 
          if (LENGTH (i) == len)
@@ -1426,6 +1427,7 @@
   register INTERVAL i, unchanged;
   register ptrdiff_t s, len;
   register int modified = 0;
+  ptrdiff_t got;
 
   if (NILP (object))
     XSETBUFFER (object, current_buffer);
@@ -1437,26 +1439,25 @@
   s = XINT (start);
   len = XINT (end) - s;
 
-  if (i->position != s)
-    {
-      /* No properties on this first interval -- return if
-         it covers the entire region.  */
-      if (! interval_has_some_properties (properties, i))
-       {
-         ptrdiff_t got = (LENGTH (i) - (s - i->position));
-         if (got >= len)
-           return Qnil;
-         len -= got;
-         i = next_interval (i);
-       }
-      /* Split away the beginning of this interval; what we don't
-        want to modify.  */
-      else
-       {
-         unchanged = i;
-         i = split_interval_right (unchanged, s - unchanged->position);
-         copy_properties (unchanged, i);
-       }
+  /* If there are no properties on this entire interval, return.  */
+  if (! interval_has_some_properties (properties, i))
+    {
+      got = (LENGTH (i) - (s - i->position));
+      do {
+       if (got >= len)
+         return Qnil;
+       len -= got;
+       i = next_interval (i);
+       got = LENGTH (i);
+      } while (! interval_has_some_properties (properties, i));
+    }
+  /* Split away the beginning of this interval; what we don't
+     want to modify.  */
+  else if (i->position != s)
+    {
+      unchanged = i;
+      i = split_interval_right (unchanged, s - unchanged->position);
+      copy_properties (unchanged, i);
     }
 
   if (BUFFERP (object))
@@ -1470,7 +1471,13 @@
       if (LENGTH (i) >= len)
        {
          if (! interval_has_some_properties (properties, i))
-           return modified ? Qt : Qnil;
+           {
+             eassert (modified);
+             if (BUFFERP (object))
+               signal_after_change (XINT (start), XINT (end) - XINT (start),
+                                    XINT (end) - XINT (start));
+             return Qt;
+           }
 
          if (LENGTH (i) == len)
            {
@@ -1512,6 +1519,7 @@
   register ptrdiff_t s, len;
   register int modified = 0;
   Lisp_Object properties;
+  ptrdiff_t got;
   properties = list_of_properties;
 
   if (NILP (object))
@@ -1524,26 +1532,25 @@
   s = XINT (start);
   len = XINT (end) - s;
 
-  if (i->position != s)
-    {
-      /* No properties on this first interval -- return if
-         it covers the entire region.  */
-      if (! interval_has_some_properties_list (properties, i))
-       {
-         ptrdiff_t got = (LENGTH (i) - (s - i->position));
-         if (got >= len)
-           return Qnil;
-         len -= got;
-         i = next_interval (i);
-       }
-      /* Split away the beginning of this interval; what we don't
-        want to modify.  */
-      else
-       {
-         unchanged = i;
-         i = split_interval_right (unchanged, s - unchanged->position);
-         copy_properties (unchanged, i);
-       }
+  /* If there are no properties on the interval, return.  */
+  if (! interval_has_some_properties_list (properties, i))
+    {
+      got = (LENGTH (i) - (s - i->position));
+      do {
+       if (got >= len)
+         return Qnil;
+       len -= got;
+       i = next_interval (i);
+       got = LENGTH (i);
+      } while (! interval_has_some_properties_list (properties, i));
+    }
+  /* Split away the beginning of this interval; what we don't
+     want to modify.  */
+  else if (i->position != s)
+    {
+      unchanged = i;
+      i = split_interval_right (unchanged, s - unchanged->position);
+      copy_properties (unchanged, i);
     }
 
   /* We are at the beginning of an interval, with len to scan.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]