Will validate container / window titles.
Fixes #3156.
* Returns the newly-allocated i3String.
*
*/
-i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes);
+i3String *i3string_from_utf8_with_length(const char *from_utf8, ssize_t num_bytes);
/**
* Build an i3String from an UTF-8 encoded string in Pango markup with fixed
*
*/
i3String *i3string_from_utf8(const char *from_utf8) {
- i3String *str = scalloc(1, sizeof(i3String));
-
- /* Get the text */
- str->utf8 = sstrdup(from_utf8);
-
- /* Compute and store the length */
- str->num_bytes = strlen(str->utf8);
-
- return str;
+ return i3string_from_utf8_with_length(from_utf8, -1);
}
/*
* Returns the newly-allocated i3String.
*
*/
-i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes) {
+i3String *i3string_from_utf8_with_length(const char *from_utf8, ssize_t num_bytes) {
i3String *str = scalloc(1, sizeof(i3String));
- /* Copy the actual text to our i3String */
- str->utf8 = scalloc(num_bytes + 1, 1);
- strncpy(str->utf8, from_utf8, num_bytes);
- str->utf8[num_bytes] = '\0';
+ /* g_utf8_make_valid NULL-terminates the string. */
+ str->utf8 = g_utf8_make_valid(from_utf8, num_bytes);
- /* Store the length */
- str->num_bytes = num_bytes;
+ /* num_bytes < 0 means NULL-terminated string, need to calculate length */
+ str->num_bytes = num_bytes < 0 ? strlen(str->utf8) : (size_t)num_bytes;
return str;
}
yajl_config(hand, yajl_allow_comments, true);
/* Allow multiple values, i.e. multiple nodes to attach */
yajl_config(hand, yajl_allow_multiple_values, true);
- /* Allow strings that are not valid UTF8. Could be possible if a container
- * name contains such characters. If yajl stops parsing because of this, an
- * in-place restart could fail: see #3156. */
+ /* We don't need to validate that the input is valid UTF8 here.
+ * tree_append_json is called in two cases:
+ * 1. With the append_layout command. json_validate is called first and will
+ * fail on invalid UTF8 characters so we don't need to recheck.
+ * 2. With an in-place restart. The rest of the codebase should be
+ * responsible for producing valid UTF8 JSON output. If not,
+ * tree_append_json will just preserve invalid UTF8 strings in the tree
+ * instead of failing to parse the layout file which could lead to
+ * problems like in #3156.
+ * Either way, disabling UTF8 validation slightly speeds up yajl. */
yajl_config(hand, yajl_dont_validate_strings, true);
json_node = con;
to_focus = NULL;
--- /dev/null
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • https://build.i3wm.org/docs/testsuite.html
+# (or docs/testsuite)
+#
+# • https://build.i3wm.org/docs/lib-i3test.html
+# (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • https://build.i3wm.org/docs/ipc.html
+# (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+# (unless you are already familiar with Perl)
+#
+# Verify that i3 does not crash when restart is issued while a window with a
+# title that contains non-UTF8 characters is open.
+# Ticket: #3156
+# Bug still in: 4.15-241-g9dc4df81
+use i3test;
+
+my $ws = fresh_workspace;
+open_window(name => "\x{AA} <-- invalid");
+
+cmd 'restart';
+does_i3_live;
+
+# Confirm that the invalid character got replaced with U+FFFD - "REPLACEMENT
+# CHARACTER"
+cmd '[title="^' . "\x{fffd}" . ' <-- invalid$"] fullscreen enable';
+is_num_fullscreen($ws, 1, 'title based criterion works');
+
+done_testing;