Subject: bug#8915: 23.3; Repeatable segmentation fault, all platforms, in character composition code

From: Kenichi Handa <[email-masked]>
Date: Thu, 07 Jul 2011 15:02:32 +0900

I'm very sorry for the late response.

In article <[email-masked]>, YAMAMOTO Mitsuharu <[email-masked]> writes:

>>>>>> On Tue, 21 Jun 2011 17:04:57 +0100, David Aspinall <[email-masked]> said:
> > There is a segfault which arises reproducibly when compose-character is
> > used near the end of a buffer.  I'm afraid I don't have a raw test case
> > but here is a recipe to reproduce it that loads the Emacs application
> > Proof General:
  
> >  wget http://proofgeneral.inf.ed.ac.uk/releases/ProofGeneral-4.0.tgz
> >  tar -xpzf ProofGeneral-4.0.tgz
> >  (cd ProofGeneral; make clean)
> >  emacs -q -l ProofGeneral/generic/proof-site.el
> >  C-x C-f Test.thy

> > Then type

> >  \<forall>

> > and Emacs segfaults.  If instead you type

> >  M-x 1 0 SPACE C-a \<forall>

> > it behaves as expected: looks like the code is running off the end of
> > the buffer.

> At least, the following change seems to avoid the crash.  But I'm not
> sure if this is a right fix at all.

> Handa-san, could you take a look at this issue?  The problematic case
> is that the addition of the `composite' property via fontification
> occurs during redisplay and the composition is found in the middle of
> the composed region.  That happens if the first part of the region had
> a non-nil `fontified' property and the second part did not, and then
> fontification-functions added the `composite' property to the whole
> region.

Could you please try the attached patch which, I think, is
cleaner.  It simply ignores a composition added by font-lock
at the first time.  The next redisplay will finds that
composition at earlier position (i.e. the starting position
of the composition), and thus handles it correctly.

---
Kenichi Handa
[email-masked]

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2011-06-18 00:37:38 +0000
+++ src/ChangeLog	2011-07-07 05:53:06 +0000
@@ -1,3 +1,10 @@
+2011-07-07  Kenichi Handa  <[email-masked]>
+
+	* composite.c (composition_compute_stop_pos): Ignore a static
+	composition starting before CHARPOS.
+
+	* xdisp.c (handle_composition_prop): Likewise.
+
 2011-06-18  YAMAMOTO Mitsuharu  <[email-masked]>
 
 	* dispnew.c (scrolling_window): Before scrolling, turn off a

=== modified file 'src/composite.c'
--- src/composite.c	2011-05-09 09:59:23 +0000
+++ src/composite.c	2011-07-07 05:47:54 +0000
@@ -1042,6 +1042,7 @@
   cmp_it->id = -1;
   cmp_it->ch = -2;
   if (find_composition (charpos, endpos, &start, &end, &prop, string)
+      && start >= charpos
       && COMPOSITION_VALID_P (start, end, prop))
     {
       cmp_it->stop_pos = endpos = start;

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2011-05-25 03:06:05 +0000
+++ src/xdisp.c	2011-07-06 08:13:42 +0000
@@ -4641,6 +4641,11 @@
       && COMPOSITION_VALID_P (start, end, prop)
       && (STRINGP (it->string) || (PT <= start || PT >= end)))
     {
+      if (start < pos)
+	/* As we can't handle this situation (perhaps, font-lock added
+	   a new composition), we just return here hoping that next
+	   redisplay will detect this composition much earlier.  */
+	return HANDLED_NORMALLY;
       if (start != pos)
 	{
 	  if (STRINGP (it->string))