summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog14
-rw-r--r--src/xsmfns.c57
2 files changed, 47 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 61f2a84a9f9..db3056ce6bd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,6 +1,20 @@
2015-03-27 Paul Eggert <eggert@cs.ucla.edu>
+ Avoid some core dumps in X session management
+ Derived from a bug report by Nicolas Richard in:
+ http://bugs.gnu.org/20191#20
+ * xsmfns.c (smc_save_yourself_CB): Don't dump core if
+ invocation-name is not a string. Initialize user-login-name if it
+ is not already initialized, and don't dump core if it is not a
+ string.
+ (create_client_leader_window): Don't dump core if x-resource-name
+ and x-resource-class are not both strings.
+ (x_session_initialize): Don't dump core if x-session-previous-id,
+ invocation-directory, and invocation-name are not strings.
+
Port user-login-name initialization to Qnil == 0
+ Derived from a bug report by Nicolas Richard in:
+ http://bugs.gnu.org/20191#20
* editfns.c (Fuser_login_name, Fuser_real_login_name)
(syms_of_editfns): Don't rely on all-bits-zero being an Elisp integer,
as this is no longer true now that Qnil == 0.
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 0e635d38ec6..375b51c4466 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -168,7 +168,6 @@ smc_save_yourself_CB (SmcConn smcConn,
int val_idx = 0, vp_idx = 0;
int props_idx = 0;
int i;
- char *cwd = get_current_dir_name ();
char *smid_opt, *chdir_opt = NULL;
/* How to start a new instance of Emacs. */
@@ -181,27 +180,34 @@ smc_save_yourself_CB (SmcConn smcConn,
props[props_idx]->vals[0].value = emacs_program;
++props_idx;
- /* The name of the program. */
- props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = xstrdup (SmProgram);
- props[props_idx]->type = xstrdup (SmARRAY8);
- props[props_idx]->num_vals = 1;
- props[props_idx]->vals = &values[val_idx++];
- props[props_idx]->vals[0].length = SBYTES (Vinvocation_name);
- props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
- ++props_idx;
+ if (STRINGP (Vinvocation_name))
+ {
+ /* The name of the program. */
+ props[props_idx] = &prop_ptr[props_idx];
+ props[props_idx]->name = xstrdup (SmProgram);
+ props[props_idx]->type = xstrdup (SmARRAY8);
+ props[props_idx]->num_vals = 1;
+ props[props_idx]->vals = &values[val_idx++];
+ props[props_idx]->vals[0].length = SBYTES (Vinvocation_name);
+ props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
+ ++props_idx;
+ }
/* User id. */
- props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = xstrdup (SmUserID);
- props[props_idx]->type = xstrdup (SmARRAY8);
- props[props_idx]->num_vals = 1;
- props[props_idx]->vals = &values[val_idx++];
- props[props_idx]->vals[0].length = SBYTES (Vuser_login_name);
- props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
- ++props_idx;
-
+ Lisp_Object user_login_name = Fuser_login_name (Qnil);
+ if (STRINGP (user_login_name))
+ {
+ props[props_idx] = &prop_ptr[props_idx];
+ props[props_idx]->name = xstrdup (SmUserID);
+ props[props_idx]->type = xstrdup (SmARRAY8);
+ props[props_idx]->num_vals = 1;
+ props[props_idx]->vals = &values[val_idx++];
+ props[props_idx]->vals[0].length = SBYTES (user_login_name);
+ props[props_idx]->vals[0].value = SDATA (user_login_name);
+ ++props_idx;
+ }
+ char *cwd = get_current_dir_name ();
if (cwd)
{
props[props_idx] = &prop_ptr[props_idx];
@@ -372,6 +378,7 @@ create_client_leader_window (struct x_display_info *dpyinfo, char *client_ID)
-1, -1, 1, 1,
CopyFromParent, CopyFromParent, CopyFromParent);
+ validate_x_resource_name ();
class_hints.res_name = SSDATA (Vx_resource_name);
class_hints.res_class = SSDATA (Vx_resource_class);
XSetClassHint (dpyinfo->display, w, &class_hints);
@@ -402,22 +409,24 @@ x_session_initialize (struct x_display_info *dpyinfo)
/* Check if we where started by the session manager. If so, we will
have a previous id. */
- if (! NILP (Vx_session_previous_id) && STRINGP (Vx_session_previous_id))
+ if (STRINGP (Vx_session_previous_id))
previous_id = SSDATA (Vx_session_previous_id);
/* Construct the path to the Emacs program. */
- if (! NILP (Vinvocation_directory))
+ if (STRINGP (Vinvocation_directory))
name_len += SBYTES (Vinvocation_directory);
- name_len += SBYTES (Vinvocation_name);
+ if (STRINGP (Vinvocation_name))
+ name_len += SBYTES (Vinvocation_name);
/* This malloc will not be freed, but it is only done once, and hopefully
not very large */
emacs_program = xmalloc (name_len + 1);
char *z = emacs_program;
- if (! NILP (Vinvocation_directory))
+ if (STRINGP (Vinvocation_directory))
z = lispstpcpy (z, Vinvocation_directory);
- lispstpcpy (z, Vinvocation_name);
+ if (STRINGP (Vinvocation_name))
+ lispstpcpy (z, Vinvocation_name);
/* The SM protocol says all callbacks are mandatory, so set up all
here and in the mask passed to SmcOpenConnection. */