escape: reject UTF-16 surrogates in \u escapes in cunescape_one() (#43079)

A `\u` escape in `cunescape_one()` was accepted for any 16-bit value
except NUL. That range `0x0000`-`0xFFFF` includes the UTF-16 surrogates
`0xD800`-`0xDFFF`, which are not valid Unicode scalar values and cannot
be encoded as valid UTF-8.
This commit is contained in:
Armaan Sandhu
2026-07-21 23:40:26 +09:00
committed by GitHub
parent cc594a83f4
commit eb03267070
2 changed files with 22 additions and 0 deletions
+7
View File
@@ -202,6 +202,13 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit,
if (c == 0 && !accept_nul)
return -EINVAL;
/* Don't allow UTF-16 surrogates, they cannot be encoded as valid UTF-8. Note we
* deliberately do *not* use unichar_is_valid() here (unlike the \U case below):
* it also rejects noncharacters such as U+FFFE, which callers legitimately round-trip
* through \u (e.g. systemd.mount-extra= parsing, see test-fstab-generator). */
if (utf16_is_surrogate(c))
return -EINVAL;
*ret = c;
r = 5;
break;