reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 309f9221a58a612bc54150badb01a7a662b7dd0b
parent 6780823b360ae657902e13ba40a92dedc2063132
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Fri, 28 Oct 2016 19:54:37 -0400

remote: improve name validaton

turns out Windows disallows weird stuff

Diffstat:
Msrc/remote.cpp | 12+++++++++---
Mtest/remote.cpp | 118++++++++++++++++++++++++++++++++++++++++++-------------------------------------
2 files changed, 72 insertions(+), 58 deletions(-)

diff --git a/src/remote.cpp b/src/remote.cpp @@ -30,12 +30,18 @@ static char DATA_DELIMITER = '|'; static bool validateName(const string &name) { - static const regex validPattern("[^~#%&*{}\\\\:<>?/+|\"]{4,24}"); + using namespace std::regex_constants; + + // see https://en.wikipedia.org/wiki/Filename#Reserved%5Fcharacters%5Fand%5Fwords + static const regex validPattern("[^*\\\\:<>?/|\"[:cntrl:]]{4,24}"); + static const regex invalidPattern( + "[\\.\x20].+|.+[\\.\x20]|CLOCK\\$|COM\\d|LPT\\d", icase); smatch match, invalid; regex_match(name, match, validPattern); + regex_match(name, invalid, invalidPattern); - return !match.empty(); + return !match.empty() && invalid.empty(); } static bool validateUrl(const string &url) @@ -44,7 +50,7 @@ static bool validateUrl(const string &url) // see http://tools.ietf.org/html/rfc3986#section-2 static const regex pattern( - "^(?:[a-z0-9._~:/?#[\\]@!$&'()*+,;=-]|%[a-f0-9]{2})+$", icase); + "(?:[a-z0-9._~:/?#[\\]@!$&'()*+,;=-]|%[a-f0-9]{2})+", icase); smatch match; regex_match(url, match, pattern); diff --git a/test/remote.cpp b/test/remote.cpp @@ -18,71 +18,79 @@ TEST_CASE("construct remote", M) { REQUIRE_FALSE(remote.isProtected()); } -TEST_CASE("construct invalid remote", M) { - SECTION("empty name") { - try { - Remote remote({}, "url"); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid name"); +TEST_CASE("remote name validation", M) { + SECTION("invalid") { + const string invalidNames[] = { + "", + "ab/cd", + "ab\\cd", + "..", + ".", + "....", + ".hidden", + "trailing.", + " leading", + "trailing ", + "ctrl\4chars", + + // Windows device names... + "CLOCK$", + "COM1", + "LPT2", + "lpt1", + }; + + for(const string &name : invalidNames) { + try { + Remote remote(name, "url"); + FAIL("'" + name + "' was allowed"); + } + catch(const reapack_error &e) { + REQUIRE(string(e.what()) == "invalid name"); + } } } - SECTION("invalid name") { - try { - Remote remote("a/", "url"); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid name"); - } - } - - SECTION("directory traversal in name") { - try { - Remote remote("..", "url"); - FAIL("dotdot was allowed"); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid name"); - } - - try { - Remote remote(".", "url"); - FAIL("single dot was allowed"); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid name"); - } - } - - SECTION("empty url") { - try { - Remote remote("name", {}); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid url"); + SECTION("valid") { + const string validNames[] = { + "1234", + "hello world", + "hello_world", + "Новая папка", + "Hello ~World~", + "Repository #1" + }; + + for(const string &name : validNames) { + try { + Remote remote(name, "url"); + } + catch(const reapack_error &e) { + FAIL("'" + name + "' was denied (" + e.what() + ')'); + } } } +} - SECTION("invalid url") { - try { - Remote remote("name", "hello world"); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "invalid url"); +TEST_CASE("remote url validation", M) { + SECTION("invalid") { + const string invalidUrls[] = { + "", + "hello world", // space should be %20 + }; + + for(const string &url : invalidUrls) { + try { + Remote remote("hello", url); + FAIL("'" + url + "' was allowed"); + } + catch(const reapack_error &e) { + REQUIRE(string(e.what()) == "invalid url"); + } } } } -TEST_CASE("unicode name") { - SECTION("cyrillic") - Remote remote("Новая папка", "url"); -} - TEST_CASE("set invalid values", M) { Remote remote;