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

Function validate_path_component

src/os/linux/pagecache.cpp:126–155  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

124}
125
126PathTrust validate_path_component(std::string_view comp) {
127 if (comp.empty()) return {false, "empty path component"};
128 if (comp == "." || comp == "..") return {false, "path traversal component"};
129 const auto* p = reinterpret_cast<const unsigned char*>(comp.data());
130 const std::size_t n = comp.size();
131 std::size_t i = 0;
132 while (i < n) {
133 const unsigned char c = p[i];
134 if (c < 0x80) {
135 // ASCII byte: apply the display-/host-safety rules.
136 if (c == 0) return {false, "embedded NUL in path component"};
137 if (c == '/') return {false, "slash in path component"};
138 if (c < 0x20 || c == 0x7f) return {false, "control byte in path component"};
139 if (is_host_forbidden_path_char(c))
140 return {false, "host-forbidden character in path component"};
141 ++i;
142 } else {
143 // Non-ASCII: accept only well-formed UTF-8; reject binary garbage.
144 const int len = utf8_sequence_len(p + i, n - i);
145 if (len == 0) return {false, "invalid UTF-8 in path component"};
146 // Reject C1 control codepoints U+0080–U+009F (0xC2 0x80–0x9F).
147 if (len == 2 && c == 0xC2 && p[i + 1] <= 0x9F)
148 return {false, "control codepoint in path component"};
149 i += static_cast<std::size_t>(len);
150 }
151 }
152 if (comp.back() == ' ' || comp.back() == '.')
153 return {false, "component has trailing space or dot"};
154 return {true, {}};
155}
156
157std::string escape_path_for_report(const std::string& s) {
158 std::string out;

Callers 1

Calls 3

utf8_sequence_lenFunction · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected