diff --git a/AUTHORS b/AUTHORS index cfb6b1795..399c59e04 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,6 +34,7 @@ The following submitted code, packages or analysis, and deserve special thanks: Jostein Berntsen Andraž 'ruskie' Levstik Irfan Siddiqui + Itay Perl Thanks to the following, who submitted detailed bug reports and excellent suggestions: @@ -65,7 +66,6 @@ suggestions: Michelle Crane Elizabeth Maxson Peter De Poorter - Itay Perl Max Muller Sander Marechal Thomas Sattler diff --git a/src/Att.cpp b/src/Att.cpp index dbe0d6b28..983950e71 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -90,6 +90,22 @@ static const char* modifierNames[] = #define NUM_MODIFIABLE_NAMES (sizeof (modifiableNames) / sizeof (modifiableNames[0])) #define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0])) +//////////////////////////////////////////////////////////////////////////////// +static inline std::string& str_replace ( + std::string &str, + const std::string& search, + const std::string& replacement) +{ + std::string::size_type pos = 0; + while ((pos = str.find (search, pos)) != std::string::npos) + { + str.replace (pos, search.length (), replacement); + pos += replacement.length (); + } + + return str; +} + //////////////////////////////////////////////////////////////////////////////// Att::Att () : mName ("") @@ -917,9 +933,7 @@ void Att::enquote (std::string& value) const // that hand-editing the pending.data file could cause. void Att::dequote (std::string& value) const { - std::string::size_type quote; - while ((quote = value.find ('"')) != std::string::npos) - value.replace (quote, 1, ""); + str_replace (value, "\"", ""); } //////////////////////////////////////////////////////////////////////////////// @@ -928,21 +942,14 @@ void Att::dequote (std::string& value) const // " -> &dquot; // [ -> &open; // ] -> &close; +// \ -> \\ (extra chars to disambiguate multi-line comment) void Att::encode (std::string& value) const { - std::string::size_type i; - - while ((i = value.find ('\t')) != std::string::npos) - value.replace (i, 1, "&tab;"); // no i18n - - while ((i = value.find ('"')) != std::string::npos) - value.replace (i, 1, "&dquot;"); // no i18n - - while ((i = value.find ('[')) != std::string::npos) - value.replace (i, 1, "&open;"); // no i18n - - while ((i = value.find (']')) != std::string::npos) - value.replace (i, 1, "&close;"); // no i18n + str_replace (value, "\t", "&tab;"); + str_replace (value, "\"", "&dquot;"); + str_replace (value, "[", "&open;"); + str_replace (value, "]", "&close;"); + str_replace (value, "\\", "\\\\"); } //////////////////////////////////////////////////////////////////////////////// @@ -956,35 +963,19 @@ void Att::encode (std::string& value) const // : <- : void Att::decode (std::string& value) const { - std::string::size_type i; - // Supported encodings. - while ((i = value.find ("&tab;")) != std::string::npos) - value.replace (i, 5, "\t"); - - while ((i = value.find ("&dquot;")) != std::string::npos) - value.replace (i, 7, "\""); - - while ((i = value.find (""")) != std::string::npos) - value.replace (i, 6, "\""); - - while ((i = value.find ("&open;")) != std::string::npos) - value.replace (i, 6, "["); - - while ((i = value.find ("&close;")) != std::string::npos) - value.replace (i, 7, "]"); + str_replace (value, "&tab;", "\t"); + str_replace (value, "&dquot;", "\""); + str_replace (value, """, "'"); + str_replace (value, "&open;", "["); + str_replace (value, "&close;", "]"); // Support for deprecated encodings. These cannot be removed or old files // will not be parsable. Not just old files - completed.data can contain // tasks formatted/encoded using these. - while ((i = value.find ("&squot;")) != std::string::npos) - value.replace (i, 7, "'"); - - while ((i = value.find (",")) != std::string::npos) - value.replace (i, 7, ","); - - while ((i = value.find (":")) != std::string::npos) - value.replace (i, 7, ":"); + str_replace (value, "&squot;", "'"); + str_replace (value, ",", ","); + str_replace (value, ":", ":"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tests/backslash.t b/src/tests/backslash.t new file mode 100755 index 000000000..8ecb4aced --- /dev/null +++ b/src/tests/backslash.t @@ -0,0 +1,52 @@ +#! /usr/bin/perl +################################################################################ +## taskwarrior - a command line task list manager. +## +## Copyright 2006 - 2010, Paul Beckingham, Federico Hernandez. +## All rights reserved. +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 2 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, write to the +## +## Free Software Foundation, Inc., +## 51 Franklin Street, Fifth Floor, +## Boston, MA +## 02110-1301 +## USA +## +################################################################################ + +use strict; +use warnings; +use Test::More tests => 3; + +# Create the rc file. +if (open my $fh, '>', 'backslash.rc') +{ + print $fh "data.location=.\n"; + close $fh; + ok (-r 'backslash.rc', 'Created backslash.rc'); +} + +# Add a description with a backslash. +qx{../task rc:backslash.rc add foo\\\\bar}; +my $output = qx{../task rc:backslash.rc ls}; +like ($output, qr/foo\\bar/, 'Backslash preserved, no parsing issues'); + +# Cleanup. +unlink 'backslash.rc'; +ok (!-r 'backslash.rc', 'Removed backslash.rc'); + +exit 0; + +################################################################################