diff --git a/src/window.c b/src/window.c index ace109e3..5485bcc3 100644 --- a/src/window.c +++ b/src/window.c @@ -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 * null-terminated strings (for compatibility reasons). Instead, we * 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_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); else 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); if (before_mgmt) { + free(new_class); free(prop); return; } run_assignments(win); + free(new_class); free(prop); } diff --git a/testcases/t/235-wm-class-change-handler.t b/testcases/t/235-wm-class-change-handler.t index e6cacded..3685b30c 100644 --- a/testcases/t/235-wm-class-change-handler.t +++ b/testcases/t/235-wm-class-change-handler.t @@ -31,16 +31,17 @@ EOT my $pid = launch_with_config($config); sub change_window_class { - my ($window, $class) = @_; + my ($window, $class, $length) = @_; my $atomname = $x->atom(name => 'WM_CLASS'); my $atomtype = $x->atom(name => 'STRING'); + $length ||= length($class) + 1; $x->change_property( PROP_MODE_REPLACE, $window->id, $atomname->id, $atomtype->id, 8, - length($class) + 1, + $length, $class ); sync_with_i3; @@ -65,6 +66,13 @@ is($con->{window_properties}->{instance}, 'special', is($con->{mark}, 'special_class_mark', '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); done_testing;