TW-1723: task info causes segfault

- Thanks to Roman Golovin.
- Calls like 'context.columns[name]' autovivify the key 'name' with a default
  ctor value, which ends up polluting the context.columns map with every unique
  attribute name, which is a lot of 'annotation_nnnnnnnnnn' attributes.
This commit is contained in:
Paul Beckingham 2015-11-15 12:57:26 -05:00
parent fdda485032
commit 79189c448c
4 changed files with 37 additions and 31 deletions

View file

@ -17,6 +17,7 @@
- TW-1704 Use Task::identifier to reference the Task in the output - TW-1704 Use Task::identifier to reference the Task in the output
- TW-1720 CmdContext uses a mix of both throw and std::cout to convey - TW-1720 CmdContext uses a mix of both throw and std::cout to convey
errors (thanks to Paul Beckingham). errors (thanks to Paul Beckingham).
- TW-1723 task info causes segfault (thanks to Roman Golovin).
- Fixed broken build for Cygwin and older GCC (thanks to Richard Boß). - Fixed broken build for Cygwin and older GCC (thanks to Richard Boß).
- The default configuration is now 256-color only. - The default configuration is now 256-color only.
- The 'columns' report now shows whether a column is modifiable or read only. - The 'columns' report now shows whether a column is modifiable or read only.

View file

@ -501,10 +501,9 @@ bool Task::is_dueyear () const
bool Task::is_udaPresent () const bool Task::is_udaPresent () const
{ {
for (auto& col : context.columns) for (auto& col : context.columns)
if (col.first.compare (0, 11, "annotation_", 11) != 0) if (col.second->is_uda () &&
if (col.second->is_uda () && has (col.first))
has (col.first)) return true;
return true;
return false; return false;
} }

View file

@ -362,28 +362,31 @@ int CmdInfo::execute (std::string& output)
std::string type; std::string type;
for (auto& att: all) for (auto& att: all)
{ {
Column* col = context.columns[att]; if (context.columns.find (att) != context.columns.end ())
if (col && col->is_uda ())
{ {
std::string value = task.get (att); Column* col = context.columns[att];
if (value != "") if (col->is_uda ())
{ {
row = view.addRow (); std::string value = task.get (att);
view.set (row, 0, col->label ()); if (value != "")
if (type == "date")
value = ISO8601d (value).toString (dateformat);
else if (type == "duration")
{ {
ISO8601p iso; row = view.addRow ();
std::string::size_type cursor = 0; view.set (row, 0, col->label ());
if (iso.parse (value, cursor))
value = (std::string) Variant ((time_t) iso, Variant::type_duration);
else
value = "PT0S";
}
view.set (row, 1, value); if (type == "date")
value = ISO8601d (value).toString (dateformat);
else if (type == "duration")
{
ISO8601p iso;
std::string::size_type cursor = 0;
if (iso.parse (value, cursor))
value = (std::string) Variant ((time_t) iso, Variant::type_duration);
else
value = "PT0S";
}
view.set (row, 1, value);
}
} }
} }
} }
@ -393,7 +396,7 @@ int CmdInfo::execute (std::string& output)
for (auto& att : all) for (auto& att : all)
{ {
if (att.substr (0, 11) != "annotation_" && if (att.substr (0, 11) != "annotation_" &&
! context.columns[att]) context.columns.find (att) == context.columns.end ())
{ {
row = view.addRow (); row = view.addRow ();
view.set (row, 0, "[" + att); view.set (row, 0, "[" + att);

View file

@ -262,16 +262,19 @@ std::string taskInfoDifferences (
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string renderAttribute (const std::string& name, const std::string& value, const std::string& format /* = "" */) std::string renderAttribute (const std::string& name, const std::string& value, const std::string& format /* = "" */)
{ {
Column* col = context.columns[name]; if (context.columns.find (name) != context.columns.end ())
if (col &&
col->type () == "date" &&
value != "")
{ {
ISO8601d d ((time_t)strtol (value.c_str (), NULL, 10)); Column* col = context.columns[name];
if (format == "") if (col &&
return d.toString (context.config.get ("dateformat")); col->type () == "date" &&
value != "")
{
ISO8601d d ((time_t)strtol (value.c_str (), NULL, 10));
if (format == "")
return d.toString (context.config.get ("dateformat"));
return d.toString (format); return d.toString (format);
}
} }
return value; return value;