2010-10-02 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Rewritten util::escapePath(). Now it does not replace bad chars:it
	performs percent-encode against them.  util::fixTaintedBasename()
	now replaces "/" with "%2F".  Added 0x7f as bad chars in
	util::detectDirTraversal().
	* src/util.cc
	* test/UtilTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-10-02 08:20:10 +00:00
parent d956ea0b70
commit d5e0046f29
3 changed files with 38 additions and 33 deletions

View File

@ -1,3 +1,12 @@
2010-10-02 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten util::escapePath(). Now it does not replace bad chars:it
performs percent-encode against them. util::fixTaintedBasename()
now replaces "/" with "%2F". Added 0x7f as bad chars in
util::detectDirTraversal().
* src/util.cc
* test/UtilTest.cc
2010-10-02 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Non-UTF8 filenames are now percent-encoded. For example, filename

View File

@ -1289,7 +1289,8 @@ std::string applyDir(const std::string& dir, const std::string& relPath)
std::string fixTaintedBasename(const std::string& src)
{
return escapePath(replace(src, A2STR::SLASH_C, A2STR::UNDERSCORE_C));
static std::string SLASH_REP = "%2F";
return escapePath(replace(src, A2STR::SLASH_C, SLASH_REP));
}
void generateRandomKey(unsigned char* key)
@ -1329,7 +1330,8 @@ bool inPrivateAddress(const std::string& ipv4addr)
bool detectDirTraversal(const std::string& s)
{
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
if(0x00 <= (*i) && (*i) <= 0x1f) {
unsigned char c = *i;
if(in(c, 0x00, 0x1f) || c == 0x7f) {
return true;
}
}
@ -1345,35 +1347,29 @@ bool detectDirTraversal(const std::string& s)
util::endsWith(s, "/..");
}
namespace {
class EscapePath {
private:
char repChar_;
public:
EscapePath(const char& repChar):repChar_(repChar) {}
char operator()(const char& c) {
if(0x00 <= c && c <=0x1f) {
return repChar_;
}
#ifdef __MINGW32__
// We don't escape '/' because we use it as a path separator.
static const char WIN_INVALID_PATH_CHARS[] =
{ '"', '*', ':', '<', '>', '?', '\\', '|' };
if(std::find(vbegin(WIN_INVALID_PATH_CHARS), vend(WIN_INVALID_PATH_CHARS),
c) != vend(WIN_INVALID_PATH_CHARS)) {
return repChar_;
}
#endif // __MINGW32__
return c;
}
};
}
std::string escapePath(const std::string& s)
{
std::string d = s;
std::transform(d.begin(), d.end(), d.begin(), EscapePath('_'));
// We don't escape '/' because we use it as a path separator.
#ifdef __MINGW32__
static const char WIN_INVALID_PATH_CHARS[] =
{ '"', '*', ':', '<', '>', '?', '\\', '|' };
#endif // __MINGW32__
std::string d;
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
unsigned char c = *i;
if(in(c, 0x00, 0x1f) || c == 0x7f
#ifdef __MINGW32__
|| std::find(vbegin(WIN_INVALID_PATH_CHARS),
vend(WIN_INVALID_PATH_CHARS),
c) != vend(WIN_INVALID_PATH_CHARS)
#endif // __MINGW32__
){
d += StringFormat("%%%02X", c).str();
} else {
d += *i;
}
}
return d;
}

View File

@ -1024,9 +1024,9 @@ void UtilTest::testApplyDir()
void UtilTest::testFixTaintedBasename()
{
CPPUNIT_ASSERT_EQUAL(std::string("a_b"), util::fixTaintedBasename("a/b"));
CPPUNIT_ASSERT_EQUAL(std::string("a%2Fb"), util::fixTaintedBasename("a/b"));
#ifdef __MINGW32__
CPPUNIT_ASSERT_EQUAL(std::string("a_b"), util::fixTaintedBasename("a\\b"));
CPPUNIT_ASSERT_EQUAL(std::string("a%5Cb"), util::fixTaintedBasename("a\\b"));
#else // !__MINGW32__
CPPUNIT_ASSERT_EQUAL(std::string("a\\b"), util::fixTaintedBasename("a\\b"));
#endif // !__MINGW32__
@ -1059,12 +1059,12 @@ void UtilTest::testDetectDirTraversal()
void UtilTest::testEscapePath()
{
CPPUNIT_ASSERT_EQUAL(std::string("foo_bar__"),
CPPUNIT_ASSERT_EQUAL(std::string("foo%00bar%00%01"),
util::escapePath(std::string("foo")+(char)0x00+
std::string("bar")+(char)0x00+
(char)0x01));
#ifdef __MINGW32__
CPPUNIT_ASSERT_EQUAL(std::string("foo_bar"), util::escapePath("foo\\bar"));
CPPUNIT_ASSERT_EQUAL(std::string("foo%5Cbar"), util::escapePath("foo\\bar"));
#else // !__MINGW32__
CPPUNIT_ASSERT_EQUAL(std::string("foo\\bar"), util::escapePath("foo\\bar"));
#endif // !__MINGW32__