| 225 | } |
| 226 | |
| 227 | class ValidFileNameCharChecker |
| 228 | { |
| 229 | private: |
| 230 | bool invalid_lut[128]; |
| 231 | public: |
| 232 | ValidFileNameCharChecker() |
| 233 | { |
| 234 | memset(invalid_lut, 0, sizeof(invalid_lut)); |
| 235 | |
| 236 | invalid_lut['<'] = true; // (less than) |
| 237 | invalid_lut['>'] = true; // (greater than) |
| 238 | invalid_lut[':'] = true; // (colon) |
| 239 | invalid_lut['"'] = true; // (double quote) |
| 240 | invalid_lut['/'] = true; // (forward slash) |
| 241 | invalid_lut['\\'] = true; // (backslash) |
| 242 | invalid_lut['|'] = true; // (vertical bar or pipe) |
| 243 | invalid_lut['?'] = true; // (question mark) |
| 244 | invalid_lut['*'] = true; // (asterisk) |
| 245 | } |
| 246 | |
| 247 | virtual ~ValidFileNameCharChecker() = default; |
| 248 | |
| 249 | // disallow copying |
| 250 | ValidFileNameCharChecker(ValidFileNameCharChecker const&) = delete; |
| 251 | void operator=(ValidFileNameCharChecker const&) = delete; |
| 252 | |
| 253 | bool is_valid(const WCHAR* s, bool bStream) const |
| 254 | { |
| 255 | if (!s) |
| 256 | return false; |
| 257 | |
| 258 | // from https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file |
| 259 | |
| 260 | for (; *s; s++) { |
| 261 | static_assert(sizeof(WCHAR) <= sizeof(size_t), "cannot fit a WCHAR in a size_t"); |
| 262 | size_t c = static_cast<size_t>(*s); |
| 263 | // control chars are allowed only in stream names |
| 264 | if (!bStream && c >= 1 && c <= 31) |
| 265 | return false; |
| 266 | // chars outside 7-bit ascii are all allowed |
| 267 | if (c > 127) |
| 268 | continue; |
| 269 | if (invalid_lut[c]) |
| 270 | return false; |
| 271 | } |
| 272 | return true; |
| 273 | } |
| 274 | |
| 275 | }; |
| 276 | |
| 277 | |
| 278 | const WCHAR * // returns UNICODE plaintext filename |
nothing calls this directly
no outgoing calls
no test coverage detected