MCPcopy Create free account
hub / github.com/MemNixFS/MemNixFS / utf8_sequence_len

Function utf8_sequence_len

src/os/linux/pagecache.cpp:98–124  ·  view source on GitHub ↗

Length (1-4) of a well-formed UTF-8 sequence starting at p with `avail` bytes remaining, or 0 if the bytes are not well-formed UTF-8. Follows the Unicode 3.9 well-formed byte-sequence table: rejects overlong encodings, UTF-16 surrogates (U+D800–U+DFFF), and codepoints above U+10FFFF, as well as lone continuation bytes and truncated sequences. This is what tells a real non-ASCII filename apart from

Source from the content-addressed store, hash-verified

96// lone continuation bytes and truncated sequences. This is what tells a real
97// non-ASCII filename apart from binary garbage in a corrupt/hostile dentry.
98int utf8_sequence_len(const unsigned char* p, std::size_t avail) {
99 const unsigned char c = p[0];
100 if (c < 0x80) return 1;
101 auto cont = [](unsigned char b, unsigned char lo, unsigned char hi) {
102 return b >= lo && b <= hi;
103 };
104 if (c >= 0xC2 && c <= 0xDF)
105 return (avail >= 2 && cont(p[1], 0x80, 0xBF)) ? 2 : 0;
106 if (c == 0xE0)
107 return (avail >= 3 && cont(p[1], 0xA0, 0xBF) && cont(p[2], 0x80, 0xBF)) ? 3 : 0;
108 if (c >= 0xE1 && c <= 0xEC)
109 return (avail >= 3 && cont(p[1], 0x80, 0xBF) && cont(p[2], 0x80, 0xBF)) ? 3 : 0;
110 if (c == 0xED) // exclude surrogates: second byte capped at 0x9F
111 return (avail >= 3 && cont(p[1], 0x80, 0x9F) && cont(p[2], 0x80, 0xBF)) ? 3 : 0;
112 if (c >= 0xEE && c <= 0xEF)
113 return (avail >= 3 && cont(p[1], 0x80, 0xBF) && cont(p[2], 0x80, 0xBF)) ? 3 : 0;
114 if (c == 0xF0)
115 return (avail >= 4 && cont(p[1], 0x90, 0xBF) && cont(p[2], 0x80, 0xBF) &&
116 cont(p[3], 0x80, 0xBF)) ? 4 : 0;
117 if (c >= 0xF1 && c <= 0xF3)
118 return (avail >= 4 && cont(p[1], 0x80, 0xBF) && cont(p[2], 0x80, 0xBF) &&
119 cont(p[3], 0x80, 0xBF)) ? 4 : 0;
120 if (c == 0xF4) // cap at U+10FFFF: second byte 0x80–0x8F
121 return (avail >= 4 && cont(p[1], 0x80, 0x8F) && cont(p[2], 0x80, 0xBF) &&
122 cont(p[3], 0x80, 0xBF)) ? 4 : 0;
123 return 0; // 0x80–0xBF lone, 0xC0/0xC1 overlong, 0xF5–0xFF out of range
124}
125
126PathTrust validate_path_component(std::string_view comp) {
127 if (comp.empty()) return {false, "empty path component"};

Callers 1

validate_path_componentFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected