utf8_char_console_width() decoded with utf8_encoded_to_unichar(), which does not check for overlong encodings, does not check unichar_is_valid(), and still accepts the obsolete five and six byte forms. Those checks live in the wrapper utf8_encoded_valid_unichar(), which is what utf8_is_valid() and ellipsize_mem() use. Over all 4244897280 NUL free byte strings of length one to four, that is the whole UTF-8 encoding space, the wrapper agrees with utf8_is_valid_n() everywhere, while the bare decoder disagrees on 8835838 of them, always by accepting more. So utf8_console_width() assigned a finite width to strings that utf8_is_valid() refuses. format-table.c measures a cell with utf8_console_width() and, if it does not fit, hands it to ellipsize(), which validates strictly, returns NULL, and is reported as -ENOMEM. A surrogate, overlong, noncharacter or five byte sequence in any cell therefore failed the whole table with a bogus out of memory error, and only once the column happened to be narrow enough to require truncation, so whether it happened at all depended on the width of the user's terminal. At other widths the invalid sequence was printed to the terminal instead. Decode with utf8_encoded_valid_unichar() so that how wide we think a string is agrees with whether we consider it valid UTF-8 in the first place. Invalid cells are now refused consistently with -EINVAL, the way the sequences that utf8_encoded_to_unichar() already rejected always were. Note that for tables this makes the refusal total rather than per field: table_data_requested_width_height() turns a SIZE_MAX width into -EINVAL, which table_format() propagates, so a cell in one of the newly rejected encodings now fails the whole table at every width. systemd-dissect and repart --dry-run put GPT partition names read straight off the image into cells without filtering them, so a crafted partition name suppresses the whole listing where before it cost one field, and only at some terminal widths. That is the intended trade: the alternative is to keep emitting raw invalid bytes to the terminal at whichever widths happen not to need truncation. Should degrading the cell rather than the table turn out to be preferable, the place for it is where the text enters the table, via utf8_escape_invalid() and friends, not in a helper whose job is to say how wide a string is. This also makes the assert(w >= 0) in utf8_escape_non_printable_full() hold by construction rather than by the accident that its own validation was stricter than the width helper's.
System and Service Manager
Details
Most documentation is available on systemd's website.
Assorted, older, general information about systemd can be found in the systemd Wiki.
Information about build requirements is provided in the README file.
Consult our NEWS file for information about what's new in the most recent systemd versions.
Please see the Code Map for information about this repository's layout and content.
Please see the Hacking guide for information on how to hack on systemd and test your modifications.
Please see our Contribution Guidelines for more information about filing GitHub Issues and posting GitHub Pull Requests.
When preparing patches for systemd, please follow our Coding Style Guidelines.
If you are looking for support, please contact our mailing list, join our IRC channel #systemd on libera.chat or Matrix channel
Stable branches with backported patches are available in the stable repo.
We have a security bug bounty program sponsored by the Sovereign Tech Fund hosted on YesWeHack
Repositories with distribution packages built from git main are available on OBS, and also repositories with packages built from the latest stable release
