From 14af994c9fb80bbdc34d43021815a42f17dbaeb1 Mon Sep 17 00:00:00 2001 From: Alexander van Gessel Date: Fri, 6 Oct 2017 12:07:11 +0200 Subject: [PATCH] Add extra filename blacklist checks Check for invalid UTF-8, overly long filenames, surrogate pairs and all control characters. --- src/addon/validation.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/addon/validation.cpp b/src/addon/validation.cpp index 911bdf73b7fc..46e50e8ae5b7 100644 --- a/src/addon/validation.cpp +++ b/src/addon/validation.cpp @@ -15,6 +15,7 @@ #include "addon/validation.hpp" #include "config.hpp" +#include "serialization/unicode_cast.hpp" #include #include @@ -46,6 +47,27 @@ namespace { } } }; + + struct addon_filename_ucs4char_illegal + { + inline bool operator()(ucs4::char_t c) const + { + switch(c){ + case ' ': + case '/': + case ':': + case '\\': + case '~': + case 0x7F: // DEL + return true; + default: + return ( + c < 0x20 || // control characters + (c >= 0xD800 && c < 0xE000) // surrogate pairs + ); + } + } + }; } bool addon_name_legal(const std::string& name) @@ -61,11 +83,16 @@ bool addon_name_legal(const std::string& name) bool addon_filename_legal(const std::string& name) { if(name.empty() || name.back() == '.' || - name.find_first_of("/:\\~ \r\n\v\t") != std::string::npos || - name.find("..") != std::string::npos) { + name.find("..") != std::string::npos || + name.size() > 255) { return false; } else { - return true; + const ucs4::string name_ucs4 = unicode_cast(name); + const std::string name_utf8 = unicode_cast(name_ucs4); + if(name != name_utf8){ // name is invalid UTF-8 + return false; + } + return std::find_if(name_ucs4.begin(), name_ucs4.end(), addon_filename_ucs4char_illegal()) == name_ucs4.end(); } }