Subject: bug#17691: 24.3.91; crash closing remote frame

From: Dmitry Antipov <[email-masked]>
Date: Thu, 05 Jun 2014 08:53:16 +0400

On 06/05/2014 01:49 AM, Ken Raeburn wrote:

> A simpler reproduction just worked for me:
>
> emacs -Q -nw
>
> in the scratch buffer, evaluate:
>
> (let ((f (make-frame-on-display ":0" '((font . "7x14")))))
>    (delete-frame f))
>
> That's killed my Emacs processes pretty reliably.
>
> Simpler still:
>
> $ emacs -Q -nw --eval '(let ((f (make-frame-on-display ":0" '"'"'((font . "7x14"))))) (delete-frame f))'
>
> The terminal window gets a frame, the X display gets a frame, the X
> frame goes away, and the terminal-mode Emacs crashes.

Please try this against emacs-24 branch or 24.3.91 (this is a backported
hybrid of trunk commits 116927 and 117126). If that works for you, this
should be incorporated into emacs-24 and included into the next pretest.

Dmitry

=== modified file 'src/font.c'
--- src/font.c	2014-03-03 19:58:20 +0000
+++ src/font.c	2014-06-05 04:43:59 +0000
@@ -2753,22 +2753,21 @@
 	  val = XCDR (val);
 	else
 	  {
-	    Lisp_Object copy;
-
 	    val = driver_list->driver->list (f, scratch_font_spec);
-	    if (NILP (val))
-	      val = zero_vector;
-	    else
-	      val = Fvconcat (1, &val);
-	    copy = copy_font_spec (scratch_font_spec);
-	    ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
-	    XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
+	    if (!NILP (val))
+	      {
+		Lisp_Object copy = copy_font_spec (scratch_font_spec);
+
+		val = Fvconcat (1, &val);
+		ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
+		XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
+	      }
 	  }
-	if (ASIZE (val) > 0
+	if (VECTORP (val) && ASIZE (val) > 0
 	    && (need_filtering
 		|| ! NILP (Vface_ignored_fonts)))
 	  val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size);
-	if (ASIZE (val) > 0)
+	if (VECTORP (val) && ASIZE (val) > 0)
 	  list = Fcons (val, list);
       }
 
@@ -2804,18 +2803,22 @@
 	&& (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
       {
 	Lisp_Object cache = font_get_cache (f, driver_list->driver);
-	Lisp_Object copy;
 
 	ASET (work, FONT_TYPE_INDEX, driver_list->driver->type);
 	entity = assoc_no_quit (work, XCDR (cache));
 	if (CONSP (entity))
-	  entity = XCDR (entity);
+	  entity = AREF (XCDR (entity), 0);
 	else
 	  {
 	    entity = driver_list->driver->match (f, work);
-	    copy = copy_font_spec (work);
-	    ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
-	    XSETCDR (cache, Fcons (Fcons (copy, entity), XCDR (cache)));
+	    if (!NILP (entity))
+	      {
+		Lisp_Object copy = copy_font_spec (work);
+		Lisp_Object match = Fvector (1, &entity);
+
+		ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
+		XSETCDR (cache, Fcons (Fcons (copy, match), XCDR (cache)));
+	      }
 	  }
 	if (! NILP (entity))
 	  break;