Merge pull request #1604 from mh21/wm-class-garbage

Cope with non-null-terminated x class properties.
This commit is contained in:
Michael Stapelberg 2015-03-30 09:12:25 +02:00
commit eb48b974df
2 changed files with 17 additions and 4 deletions

View File

@ -26,13 +26,16 @@ void window_update_class(i3Window *win, xcb_get_property_reply_t *prop, bool bef
/* We cannot use asprintf here since this property contains two /* We cannot use asprintf here since this property contains two
* null-terminated strings (for compatibility reasons). Instead, we * null-terminated strings (for compatibility reasons). Instead, we
* use strdup() on both strings */ * use strdup() on both strings */
char *new_class = xcb_get_property_value(prop); const size_t prop_length = xcb_get_property_value_length(prop);
char *new_class = smalloc(prop_length + 1);
memcpy(new_class, xcb_get_property_value(prop), prop_length);
new_class[prop_length] = '\0';
FREE(win->class_instance); FREE(win->class_instance);
FREE(win->class_class); FREE(win->class_class);
win->class_instance = sstrdup(new_class); win->class_instance = sstrdup(new_class);
if ((strlen(new_class) + 1) < (size_t)xcb_get_property_value_length(prop)) if ((strlen(new_class) + 1) < prop_length)
win->class_class = sstrdup(new_class + strlen(new_class) + 1); win->class_class = sstrdup(new_class + strlen(new_class) + 1);
else else
win->class_class = NULL; win->class_class = NULL;
@ -40,12 +43,14 @@ void window_update_class(i3Window *win, xcb_get_property_reply_t *prop, bool bef
win->class_instance, win->class_class); win->class_instance, win->class_class);
if (before_mgmt) { if (before_mgmt) {
free(new_class);
free(prop); free(prop);
return; return;
} }
run_assignments(win); run_assignments(win);
free(new_class);
free(prop); free(prop);
} }

View File

@ -31,16 +31,17 @@ EOT
my $pid = launch_with_config($config); my $pid = launch_with_config($config);
sub change_window_class { sub change_window_class {
my ($window, $class) = @_; my ($window, $class, $length) = @_;
my $atomname = $x->atom(name => 'WM_CLASS'); my $atomname = $x->atom(name => 'WM_CLASS');
my $atomtype = $x->atom(name => 'STRING'); my $atomtype = $x->atom(name => 'STRING');
$length ||= length($class) + 1;
$x->change_property( $x->change_property(
PROP_MODE_REPLACE, PROP_MODE_REPLACE,
$window->id, $window->id,
$atomname->id, $atomname->id,
$atomtype->id, $atomtype->id,
8, 8,
length($class) + 1, $length,
$class $class
); );
sync_with_i3; sync_with_i3;
@ -65,6 +66,13 @@ is($con->{window_properties}->{instance}, 'special',
is($con->{mark}, 'special_class_mark', is($con->{mark}, 'special_class_mark',
'A `for_window` assignment should run for a match when the window changes class'); 'A `for_window` assignment should run for a match when the window changes class');
change_window_class($win, "abcdefghijklmnopqrstuv\0abcd", 24);
$con = @{get_ws_content($ws)}[0];
is($con->{window_properties}->{class}, 'a',
'Non-null-terminated strings should be handled correctly');
exit_gracefully($pid); exit_gracefully($pid);
done_testing; done_testing;