diff --git a/ChangeLog b/ChangeLog index 4f3728955..266be29e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,12 +35,17 @@ + Fixed bug #538, where some color legend items were not readable. + Fixed bug #539, where the man page task-color(5) contained a line that began with a ' and was not displayed. + + Fixed bug #540, where user names containing @s could not be parsed + Fixed bug #542, which sorted the countdown columns incorrectly (thanks to Michelle Crane). + Fixed bug #555, which caused a segfault when logging a task with a project (thanks to Itay Perl). + + Fixed bug #570, which used unsupported brace expansion with dash (default + /bin/sh in Ubuntu) + Fixed bug #579, which displayed incorrect counts when using the 'limit:N' filter (thanks to Thomas Sattler). + + Fixed bug #580, where reusing the merge uri for autopush failed when the + uri was taken from taskrc ------ old releases ------------------------------ diff --git a/doc/man/task-sync.5 b/doc/man/task-sync.5 index 35428a7bc..f8b8ecb1d 100644 --- a/doc/man/task-sync.5 +++ b/doc/man/task-sync.5 @@ -134,6 +134,21 @@ https://host[:port]/path/to/undo.data ftp://[user@]host[:port]/path/to/undo.data .RE +You can use single quotes to encapsulate user names that contain delimiting +characters like '@', '/' or ':', e.g.: + +.br +.RS +ssh://'user@name'@host/ +.RE + +Remember to escape the quotes on your shell: + +.br +.RS +$ task push ftp://\'user@name\':host/ +.RE + .SH CONFLICTS When modifications on the local and remote machine conflict, for example if both machines change the project name of the same task to different values, diff --git a/src/Uri.cpp b/src/Uri.cpp index 87c57d74a..208a46b21 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -198,54 +198,74 @@ void Uri::parse () } std::string::size_type pos; - std::string uripart; - std::string pathDelimiter = "/"; + std::string uripart; + std::string pathDelimiter = "/"; - user = ""; - port = ""; + user = ""; + port = ""; // skip ^.*:// if ((pos = data.find ("://")) != std::string::npos) - { - protocol = data.substr(0, pos); - data = data.substr (pos+3); - // standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data - pathDelimiter = "/"; - } - else - { - protocol = "ssh"; - // scp-like syntax: [user@]host.xz:path/to/undo.data - pathDelimiter = ":"; - } + { + protocol = data.substr(0, pos); + data = data.substr (pos+3); + // standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data + pathDelimiter = "/"; + } + else + { + protocol = "ssh"; + // scp-like syntax: [user@]host.xz:path/to/undo.data + pathDelimiter = ":"; + } - // get host part - if ((pos = data.find (pathDelimiter)) != std::string::npos) - { - host = data.substr (0, pos); - path = data.substr (pos+1); - } - else - { + // user delimited by single quotes? + if ( data[0] == '\'' + && (pos = data.find("'", 1)) != std::string::npos ) + { + if (data[pos+1] == '@') + { + // end of user name + user = data.substr (1, pos-1); + data = data.substr (pos+2); + } + else + { + throw std::string ("Could not parse uri '") + data + "', wrong usage of single quotes."; + } + } + else + { + // find user name + if ((pos = data.find ("@")) != std::string::npos) + { + user = data.substr (0, pos); + data = data.substr (pos+1); + } + } + + // get host, port and path + if ((pos = data.find (pathDelimiter)) != std::string::npos) + { + host = data.substr (0, pos); + path = data.substr (pos+1); + } + else + { throw std::string ("The uri '") + data + "' is not in the expected format."; - } + } - // parse host - if ((pos = host.find ("@")) != std::string::npos) - { - user = host.substr (0, pos); - host = host.substr (pos+1); - } - - // remark: this find() will never be != npos for scp-like syntax - // because we found pathDelimiter, which is ":", before - if ((pos = host.find (":")) != std::string::npos) - { - port = host.substr (pos+1); - host = host.substr (0,pos); - } + // port specified? + // remark: this find() will never be != npos for scp-like syntax + // because we found pathDelimiter, which is ":", before + if ((pos = host.find (":")) != std::string::npos) + { + port = host.substr (pos+1); + host = host.substr (0,pos); + } parsed = true; } //////////////////////////////////////////////////////////////////////////////// +// vim: et ts=2 sw=2 diff --git a/src/tests/uri.t.cpp b/src/tests/uri.t.cpp index 1d8913a1a..3af786331 100644 --- a/src/tests/uri.t.cpp +++ b/src/tests/uri.t.cpp @@ -35,7 +35,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (30); + UnitTest t (44); Uri uri1 ("asfd://user@host/folder/"); uri1.parse (); @@ -88,6 +88,29 @@ int main (int argc, char** argv) uri6.parse (); t.is (uri6.path, "/home/user/.task/", "Uri::expand() test"); + Uri uri7 ("ftp://'user@name'@host:321/path/to/x"); + uri7.parse (); + t.is (uri7.user, "user@name", "Uri::parse() : ftp://'user@name'@host:321/path/to/x"); + t.is (uri7.host, "host", "Uri::parse() : ftp://'user@name'@host:321/path/to/x"); + t.is (uri7.port, "321", "Uri::parse() : ftp://'user@name'@host:321/path/to/x"); + t.is (uri7.path, "path/to/x", "Uri::parse() : ftp://'user@name'@host:321/path/to/x"); + t.is (uri7.protocol, "ftp", "Uri::parse() : ftp://'user@name'@host:321/path/to/x"); + + Uri uri8 ("http://'us/er@n:ame'@host/path/to/x"); + uri8.parse (); + t.is (uri8.user, "us/er@n:ame", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x"); + t.is (uri8.host, "host", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x"); + t.is (uri8.port, "", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x"); + t.is (uri8.path, "path/to/x", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x"); + t.is (uri8.protocol, "http", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x"); + + Uri uri9 ("'user@name'@host:path/to/x"); + uri9.parse (); + t.is (uri9.user, "user@name", "Uri::parse() : 'user@name'@host:path/to/x"); + t.is (uri9.host, "host", "Uri::parse() : 'user@name'@host:path/to/x"); + t.is (uri9.port, "", "Uri::parse() : 'user@name'@host:path/to/x"); + t.is (uri9.path, "path/to/x", "Uri::parse() : 'user@name'@host:path/to/x"); + return 0; }