Fix potential crash when there are errors in a statistics script

This commit is contained in:
Twan van Laarhoven
2020-06-01 14:11:40 +02:00
parent 7952a889c9
commit f9d18ac3c8
3 changed files with 22 additions and 14 deletions
+2 -1
View File
@@ -85,9 +85,10 @@ GraphData::GraphData(const GraphDataPre& d)
{ {
// find groups on each axis // find groups on each axis
size_t i = 0; size_t i = 0;
FOR_EACH(a, axes) { for (auto const& a : axes) {
map<String,UInt,SmartLess> counts; // note: default constructor for UInt() does initialize to 0 map<String,UInt,SmartLess> counts; // note: default constructor for UInt() does initialize to 0
FOR_EACH_CONST(e, d.elements) { FOR_EACH_CONST(e, d.elements) {
assert(e->values.size() == axes.size());
counts[e->values[i]] += 1; counts[e->values[i]] += 1;
} }
if (a->numeric) { if (a->numeric) {
+16 -12
View File
@@ -28,7 +28,9 @@ DECLARE_LOCAL_EVENT_TYPE(EVENT_GRAPH_SELECT, <not used>)
// ----------------------------------------------------------------------------- : Graph data // ----------------------------------------------------------------------------- : Graph data
/// A group in a table or graph /// A group in a table or graph
/** A group is rendered as a single bar or pie slice */ /** This corresponds to a specific value on an axis. For example "red" would be a GraphGroup for the "color" GraphAxis
* A group is rendered as a single bar or pie slice.
*/
class GraphGroup : public IntrusivePtrBase<GraphGroup> { class GraphGroup : public IntrusivePtrBase<GraphGroup> {
public: public:
GraphGroup(const String& name, UInt size, const Color& color = *wxBLACK) GraphGroup(const String& name, UInt size, const Color& color = *wxBLACK)
@@ -62,17 +64,17 @@ public:
, order(order) , order(order)
{} {}
String name; ///< Name/label of this axis String name; ///< Name/label of this axis
AutoColor auto_color; ///< Automatically assign colors to the groups on this axis AutoColor auto_color; ///< Automatically assign colors to the groups on this axis
vector<GraphGroup> groups; ///< Groups along this axis vector<GraphGroup> groups; ///< Groups along this axis
bool numeric; ///< Numeric axis? bool numeric; ///< Numeric axis?
double bin_size; ///< Group numeric values into bins of this size double bin_size; ///< Group numeric values into bins of this size
UInt max; ///< Maximum size of the groups UInt max; ///< Maximum size of the groups
UInt total; ///< Sum of the size of all groups UInt total; ///< Sum of the size of all groups
double mean_value; ///< Mean value, only for numeric axes double mean_value; ///< Mean value, only for numeric axes
double max_value; ///< Maximal value, only for numeric axes double max_value; ///< Maximal value, only for numeric axes
const map<String,Color>* colors; ///< Colors for each choice (optional) const map<String,Color>* colors; ///< Colors for each choice (optional)
const vector<String>* order; ///< Order of the items (optional) const vector<String>* order; ///< Order of the items (optional)
/// Add a graph group /// Add a graph group
void addGroup(const String& name, UInt size); void addGroup(const String& name, UInt size);
@@ -88,6 +90,8 @@ public:
}; };
/// Data to be displayed in a graph, not processed yet /// Data to be displayed in a graph, not processed yet
/** Requires: for (e : elements) e.values.size() == axes.size()
*/
class GraphDataPre { class GraphDataPre {
public: public:
vector<GraphAxisP> axes; vector<GraphAxisP> axes;
+4 -1
View File
@@ -477,7 +477,7 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
// find values for each card // find values for each card
for (size_t i = 0 ; i < set->cards.size() ; ++i) { for (size_t i = 0 ; i < set->cards.size() ; ++i) {
Context& ctx = set->getContext(set->cards[i]); Context& ctx = set->getContext(set->cards[i]);
GraphElementP e(new GraphElement(i)); GraphElementP e = make_intrusive<GraphElement>(i);
bool show = true; bool show = true;
FOR_EACH(dim, dims) { FOR_EACH(dim, dims) {
try { try {
@@ -490,9 +490,12 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
} }
} catch (ScriptError const& e) { } catch (ScriptError const& e) {
handle_error(ScriptError(e.what() + _("\n in script for statistics dimension '") + dim->name + _("'"))); handle_error(ScriptError(e.what() + _("\n in script for statistics dimension '") + dim->name + _("'")));
show = false;
break;
} }
} }
if (show) { if (show) {
assert(e->values.size() == dims.size());
d.elements.push_back(e); d.elements.push_back(e);
} }
} }