CVS update by aidan xemacs/src, frame-x.c, objects-xlike-inc.c ...

xemacs-cvs at xemacs.org xemacs-cvs at xemacs.org
Sun Nov 12 08:40:19 EST 2006


  User: aidan   
  Date: 06/11/12 14:40:19

  Modified:    xemacs/src ChangeLog charset.h faces.c faces.h frame-gtk.c
                        frame-x.c mule-charset.c objects-gtk.c
                        objects-xlike-inc.c window.c
Log:
Prevent a crash if the ASCII charset registries match nothing.

Revision  Changes    Path
1.1011    +40 -0     XEmacs/xemacs/src/ChangeLog

Index: ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.1010
retrieving revision 1.1011
diff -u -p -r1.1010 -r1.1011
--- ChangeLog	2006/11/11 16:05:37	1.1010
+++ ChangeLog	2006/11/12 13:40:04	1.1011
@@ -1,3 +1,43 @@
+2006-11-12  Aidan Kehoe  <kehoea at parhasard.net>
+
+	* charset.h:
+	* mule-charset.c (set_charset_registries):
+	Provide a C-accessible version of set-charset-registries that
+	doesn't error. Called from x_find_charset_font. 
+
+	* faces.c (ensure_face_cachel_contains_charset):
+	Correct my spelling. 
+	
+	* faces.c (update_EmacsFrame):
+	Don't update the frame if it isn't live. 
+	
+	* faces.h:
+	Add some documentation on FACE_FONT. 
+
+	* frame-gtk.c (gtk_update_frame_external_traits):
+	* frame-x.c (x_update_frame_external_traits):
+	In the event that FACE_FONT has deleted the frame, don't
+	manipulate it further in update_frame_external_traits.
+
+	* mule-charset.c:
+
+	* mule-charset.c (Fset_charset_registries):
+	Don't allow XLFD wildcards in charset registries. Call the
+	factored-out C-callable version instead of implementing the guts
+	of the function here. 
+
+	* objects-gtk.c:
+	#include "charset.h"
+
+	* objects-xlike-inc.c (x_find_charset_font,
+	gtk_find_charset_font): In the event that the charset is ASCII and
+	we haven't matched anything up to now, even with a pattern of "*",
+	add "iso8859-1" to the charset's registry and try again.
+	
+	* window.c (window_pixel_width_to_char_width):
+	The default width of a face may be zero; only divide by it if it's
+	nonzero. 
+	
 2006-11-11  Aidan Kehoe  <kehoea at parhasard.net>
 
 	* specifier.c:



1.16      +2 -0      XEmacs/xemacs/src/charset.h

Index: charset.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/charset.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -p -r1.15 -r1.16
--- charset.h	2006/11/05 22:31:43	1.15
+++ charset.h	2006/11/12 13:40:07	1.16
@@ -574,6 +574,8 @@ void encode_unicode_char (Lisp_Object US
 			  int USED_IF_MULE (l), unsigned_char_dynarr *dst,
 			  enum unicode_type type, unsigned int little_endian);
 
+void set_charset_registries(Lisp_Object charset, Lisp_Object registries);
+
 EXFUN (Funicode_to_char, 2);
 EXFUN (Fchar_to_unicode, 1); 
 



1.51      +4 -1      XEmacs/xemacs/src/faces.c

Index: faces.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/faces.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -p -r1.50 -r1.51
--- faces.c	2006/11/05 22:31:43	1.50
+++ faces.c	2006/11/12 13:40:07	1.51
@@ -1162,7 +1162,7 @@ ensure_face_cachel_contains_charset (str
     /* Lookup the face again, this time allowing the fallback. If this
        succeeds, it'll give a font intended for the script in question,
        which is preferable to translating to ISO10646-1 and using the
-       fixed-with fallback.  */
+       fixed-width fallback.  */
     new_val = face_property_matching_instance (face, Qfont,
 					       charset, domain,
 					       ERROR_ME_DEBUG_WARN, 0,
@@ -1840,6 +1840,9 @@ static void
 update_EmacsFrame (Lisp_Object frame, Lisp_Object name)
 {
   struct frame *frm = XFRAME (frame);
+
+  if (!FRAME_LIVE_P(frm))
+    return;
 
   if (EQ (name, Qfont))
     MARK_FRAME_SIZE_SLIPPED (frm);



1.19      +4 -0      XEmacs/xemacs/src/faces.h

Index: faces.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/faces.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -p -r1.18 -r1.19
--- faces.h	2006/11/05 22:31:43	1.18
+++ faces.h	2006/11/12 13:40:08	1.19
@@ -386,6 +386,10 @@ Lisp_Object face_property_matching_insta
   FACE_PROPERTY_INSTANCE (face, Qforeground, domain, 0, Qzero)
 #define FACE_BACKGROUND(face, domain)					\
   FACE_PROPERTY_INSTANCE (face, Qbackground, domain, 0, Qzero)
+
+/* Calling this function on the default face with the ASCII character set
+   may delete any X11 frames; see the code at the end of
+   x_find_charset_font. */
 #define FACE_FONT(face, domain, charset)				\
   face_property_matching_instance (face, Qfont, charset, domain,	\
 				   ERROR_ME_DEBUG_WARN, 0, Qzero,	\



1.23      +11 -0     XEmacs/xemacs/src/frame-gtk.c

Index: frame-gtk.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/frame-gtk.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -p -r1.22 -r1.23
--- frame-gtk.c	2005/11/25 01:42:02	1.22
+++ frame-gtk.c	2006/11/12 13:40:08	1.23
@@ -1430,6 +1430,17 @@ gtk_update_frame_external_traits (struct
    {
      Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii);
 
+     /* It may be that instantiating the font has deleted the frame (will
+	happen if the user has specified a charset registry for ASCII that
+	isn't available on the server, and our fallback of iso8859-1 isn't
+	available; something vanishingly rare.) In that case, return from
+	this function. */
+
+     if (!FRAME_LIVE_P(frm))
+       {
+	 return;
+       }
+
      if (!EQ (font, Vthe_null_font_instance))
      {
 	 /* #### BILL!!! The X code set the XtNfont property of the



1.76      +11 -0     XEmacs/xemacs/src/frame-x.c

Index: frame-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/frame-x.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -p -r1.75 -r1.76
--- frame-x.c	2006/06/19 18:49:23	1.75
+++ frame-x.c	2006/11/12 13:40:08	1.76
@@ -2734,6 +2734,17 @@ x_update_frame_external_traits (struct f
    {
      Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii);
 
+     /* It may be that instantiating the font has deleted the frame (will
+	happen if the user has specified a charset registry for ASCII that
+	isn't available on the server, and our fallback of iso8859-1 isn't
+	available; something vanishingly rare.) In that case, return from
+	this function without further manipulation of the dead frame. */
+
+     if (!FRAME_LIVE_P(frm))
+       {
+	 return;
+       }
+
      /* #### what to do about Xft?  I don't think the font is actually used
 	to compute cell size for computing frame pixel dimensions (see call
 	to EmacsFrameRecomputeCellSize() below); where is it used? -- sjt



1.51      +19 -3     XEmacs/xemacs/src/mule-charset.c

Index: mule-charset.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/mule-charset.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -p -r1.50 -r1.51
--- mule-charset.c	2006/11/07 14:04:56	1.50
+++ mule-charset.c	2006/11/12 13:40:08	1.51
@@ -883,6 +883,14 @@ Set the `ccl-program' property of CHARSE
   return Qnil;
 }
 
+void
+set_charset_registries(Lisp_Object charset, Lisp_Object registries)
+{
+  XCHARSET_REGISTRIES (charset) = registries;
+  invalidate_charset_font_caches (charset);
+  face_property_was_changed (Vdefault_face, Qfont, Qglobal);
+}
+
 DEFUN ("set-charset-registries", Fset_charset_registries, 2, 2, 0, /*
 Set the `registries' property of CHARSET to REGISTRIES.
 
@@ -913,11 +921,19 @@ would be:
 	  invalid_argument("Not an X11 REGISTRY-ENCODING combination", 
 			   XVECTOR_DATA(registries)[i]);
 	}
+
+      if (qxestrchr(XSTRING_DATA(XVECTOR_DATA(registries)[i]), '*') ||
+	  qxestrchr(XSTRING_DATA(XVECTOR_DATA(registries)[i]), '?'))
+	{
+	  invalid_argument
+	    ("XLFD wildcards not allowed in charset-registries", 
+	     XVECTOR_DATA(registries)[i]);
+
+	}
     }
 
-  XCHARSET_REGISTRIES (charset) = registries;
-  invalidate_charset_font_caches (charset);
-  face_property_was_changed (Vdefault_face, Qfont, Qglobal);
+  set_charset_registries(charset, registries);
+
   return Qnil;
 }
 



1.19      +1 -0      XEmacs/xemacs/src/objects-gtk.c

Index: objects-gtk.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/objects-gtk.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -p -r1.18 -r1.19
--- objects-gtk.c	2006/11/05 22:31:44	1.18
+++ objects-gtk.c	2006/11/12 13:40:09	1.19
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "lisp.h"
 
 #include "buffer.h"
+#include "charset.h"
 #include "device-impl.h"
 #include "insdel.h"
 



1.4       +86 -0     XEmacs/xemacs/src/objects-xlike-inc.c

Index: objects-xlike-inc.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/objects-xlike-inc.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -p -r1.3 -r1.4
--- objects-xlike-inc.c	2006/11/05 22:31:45	1.3
+++ objects-xlike-inc.c	2006/11/12 13:40:09	1.4
@@ -764,6 +764,92 @@ x_find_charset_font (Lisp_Object device,
 					    charset, stage);
     }
 
+  /* In the event that the charset is ASCII and we haven't matched
+     anything up to now, even with a pattern of "*", add "iso8859-1"
+     to the charset's registry and try again. Not returning a result
+     for ASCII means our frame geometry calculations are
+     inconsistent, and that we may crash. */
+
+  if (1 == xlfd_length && EQ(charset, Vcharset_ascii) && NILP(result)
+      && ('*' == eigetch(ei_xlfd_without_registry, 0)))
+
+    {
+      int have_latin1 = 0;
+
+      /* Set this to, for example, is08859-1 if you want to see the
+	 error behaviour. */
+
+#define FALLBACK_ASCII_REGISTRY "iso8859-1" 
+
+      for (j = 0; j < registries_len; ++j)
+	{
+	  if (0 == qxestrcasecmp(XSTRING_DATA(XVECTOR_DATA(registries)[j]),
+				 FALLBACK_ASCII_REGISTRY))
+	    {
+	      have_latin1 = 1;
+	      break;
+	    }
+	}
+
+      if (!have_latin1)
+	{
+	  Lisp_Object new_registries = make_vector(registries_len + 1, Qnil);
+
+	  warn_when_safe (Qface, Qwarning,
+			  "Your ASCII charset registries contain  nothing "
+			  "sensible.  Adding `" FALLBACK_ASCII_REGISTRY "'.");
+
+	  XVECTOR_DATA(new_registries)[0]
+	    = build_string(FALLBACK_ASCII_REGISTRY);
+
+	  memcpy(XVECTOR_DATA(new_registries) + 1,
+		 XVECTOR_DATA(registries),
+		 sizeof XVECTOR_DATA(registries)[0] * 
+		 XVECTOR_LENGTH(registries));
+
+	  /* Calling set_charset_registries instead of overwriting the
+	     value directly, to allow the charset font caches to be
+	     invalidated and a change to the default face to be
+	     noted.  */
+	  set_charset_registries(charset, new_registries);
+
+	  /* And recurse. */
+	  result = 
+	    DEVMETH_OR_GIVEN (XDEVICE (device), find_charset_font,
+			      (device, font, charset, stage),
+			      result);
+	}
+      else
+	{
+	  DECLARE_EISTRING (ei_connection_name);
+
+	  /* We preserve a copy of the connection name for the error message
+	     after the device is deleted. */
+	  eicpy_lstr (ei_connection_name, 
+		      DEVICE_CONNECTION (XDEVICE(device)));
+
+	  stderr_out ("Cannot find a font for ASCII, deleting device on %s\n",
+		      eidata (ei_connection_name));
+
+	  io_error_delete_device (device);
+
+	  /* Do a normal warning in the event that we have other, non-X
+	     frames available. (If we don't, io_error_delete_device will
+	     have exited.) */
+	  warn_when_safe 
+	    (Qface, Qerror,
+	     "Cannot find a font for ASCII, deleting device on %s.\n"
+	     "\n"
+	     "Your X server fonts appear to be inconsistent; fix them, or\n"
+	     "the next frame you create on that DISPLAY will crash this\n"
+	     "XEmacs.   At a minimum, provide one font with an XLFD ending\n"
+	     "in `" FALLBACK_ASCII_REGISTRY "', so we can work out what size\n"
+	     "a frame should be. ",
+	     eidata (ei_connection_name));
+	}
+
+    }
+
   /* This function used to return the font spec, in the case where a font
      didn't exist on the X server but it did match the charset. We're not
      doing that any more, because none of the other platform code does, and



1.93      +3 -2      XEmacs/xemacs/src/window.c

Index: window.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/window.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -p -r1.92 -r1.93
--- window.c	2006/06/21 17:30:37	1.92
+++ window.c	2006/11/12 13:40:09	1.93
@@ -4250,7 +4250,7 @@ window_pixel_width_to_char_width (struct
 				  int include_margins_p)
 {
   int avail_width;
-  int char_width;
+  int char_width = 0;
   int defheight, defwidth;
   Lisp_Object window = wrap_window (w);
 
@@ -4263,7 +4263,8 @@ window_pixel_width_to_char_width (struct
 
   default_face_height_and_width (window, &defheight, &defwidth);
 
-  char_width = (avail_width / defwidth);
+  if (defwidth) 
+    char_width = (avail_width / defwidth);
 
   /* It's the calling function's responsibility to check these values
      and make sure they're not out of range.





More information about the XEmacs-CVS mailing list