diff --git a/src/Config.cpp b/src/Config.cpp index 09f9434de..a158b2a05 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -342,6 +342,7 @@ std::string Config::_defaults = "list.all.tags=no # Include old tag names in 'tags' command\n" "print.empty.columns=no # Print columns which have no data for any task\n" "debug=no # Display diagnostics\n" + "obfuscate=no # Obfuscate data for error reporting\n" "fontunderline=yes # Uses underlines rather than -------\n" "shell.prompt=task> # Prompt used by the shell command\n" "\n" diff --git a/src/ViewTask.cpp b/src/ViewTask.cpp index 5414bec47..5fa90353e 100644 --- a/src/ViewTask.cpp +++ b/src/ViewTask.cpp @@ -114,6 +114,7 @@ std::string ViewTask::render (std::vector & data, std::vector & seque { context.timer_render.start (); + bool const obfuscate = context.config.getBoolean ("obfuscate"); bool const print_empty_columns = context.config.getBoolean ("print.empty.columns"); std::vector nonempty_columns; std::vector nonempty_sort; @@ -321,6 +322,10 @@ std::string ViewTask::render (std::vector & data, std::vector & seque if (cells[c].size () > max_lines) max_lines = cells[c].size (); + + if (obfuscate) + for (unsigned int line = 0; line < cells[c].size (); ++line) + cells[c][line] = obfuscateText (cells[c][line]); } // Listing breaks are simply blank lines inserted when a column value diff --git a/src/ViewText.cpp b/src/ViewText.cpp index 82021030b..adf03a46f 100644 --- a/src/ViewText.cpp +++ b/src/ViewText.cpp @@ -114,6 +114,8 @@ void ViewText::set (int row, int col, Color color) //////////////////////////////////////////////////////////////////////////////// std::string ViewText::render () { + bool const obfuscate = context.config.getBoolean ("obfuscate"); + // Determine minimal, ideal column widths. std::vector minimal; std::vector ideal; @@ -265,6 +267,10 @@ std::string ViewText::render () if (cells[col].size () > max_lines) max_lines = cells[col].size (); + + if (obfuscate) + for (unsigned int line = 0; line < cells[col].size (); ++line) + cells[col][line] = obfuscateText (cells[col][line]); } for (unsigned int i = 0; i < max_lines; ++i) diff --git a/src/text.cpp b/src/text.cpp index e2e02b1fb..80aec833e 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -624,6 +624,38 @@ int strippedLength (const std::string& input) return count; } +//////////////////////////////////////////////////////////////////////////////// +const std::string obfuscateText (const std::string& input) +{ + std::stringstream output; + std::string::size_type i = 0; + int character; + bool inside = false; + + while ((character = utf8_next_char (input, i))) + { + if (inside) + { + output << (char) character; + + if (character == 'm') + inside = false; + } + else + { + if (character == 033) + inside = true; + + if (inside || character == ' ') + output << (char) character; + else + output << 'x'; + } + } + + return output.str (); +} + //////////////////////////////////////////////////////////////////////////////// const std::string format (char value) { diff --git a/src/text.h b/src/text.h index 56fab1416..7f412e1f1 100644 --- a/src/text.h +++ b/src/text.h @@ -55,6 +55,7 @@ bool closeEnough (const std::string&, const std::string&, unsigned int minLength std::string::size_type find (const std::string&, const std::string&, bool sensitive = true); std::string::size_type find (const std::string&, const std::string&, std::string::size_type, bool sensitive = true); int strippedLength (const std::string&); +const std::string obfuscateText (const std::string&); const std::string format (char); const std::string format (int); const std::string formatHex (int);