mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-26 02:40:43 -06:00
Avoid unnecessary memory allocation in dom_tree_to_gnc_numeric()
Return a gnc_numeric instead of allocations that every caller has to free. This makes it easier to fix the use after free in the unit test function equals_node_val_vs_split_internal() where the expression in the return statement wants to use the allocated gnc_numeric.
This commit is contained in:
parent
fe526a6043
commit
d7b2b06bae
@ -151,11 +151,7 @@ static gboolean
|
|||||||
set_numeric (xmlNodePtr node, GncBillTerm* term,
|
set_numeric (xmlNodePtr node, GncBillTerm* term,
|
||||||
void (*func) (GncBillTerm*, gnc_numeric))
|
void (*func) (GncBillTerm*, gnc_numeric))
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
|
func (term, dom_tree_to_gnc_numeric (node));
|
||||||
g_return_val_if_fail (num, FALSE);
|
|
||||||
|
|
||||||
func (term, *num);
|
|
||||||
g_free (num);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,14 +289,8 @@ static gboolean
|
|||||||
customer_discount_handler (xmlNodePtr node, gpointer cust_pdata)
|
customer_discount_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||||
{
|
{
|
||||||
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
|
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
|
||||||
gnc_numeric* val;
|
|
||||||
|
|
||||||
val = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (val, FALSE);
|
|
||||||
|
|
||||||
gncCustomerSetDiscount (pdata->customer, *val);
|
|
||||||
g_free (val);
|
|
||||||
|
|
||||||
|
gncCustomerSetDiscount (pdata->customer, dom_tree_to_gnc_numeric (node));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,14 +298,8 @@ static gboolean
|
|||||||
customer_credit_handler (xmlNodePtr node, gpointer cust_pdata)
|
customer_credit_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||||
{
|
{
|
||||||
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
|
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
|
||||||
gnc_numeric* val;
|
|
||||||
|
|
||||||
val = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (val, FALSE);
|
|
||||||
|
|
||||||
gncCustomerSetCredit (pdata->customer, *val);
|
|
||||||
g_free (val);
|
|
||||||
|
|
||||||
|
gncCustomerSetCredit (pdata->customer, dom_tree_to_gnc_numeric (node));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,13 +229,8 @@ static gboolean
|
|||||||
employee_workday_handler (xmlNodePtr node, gpointer employee_pdata)
|
employee_workday_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||||
{
|
{
|
||||||
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
|
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
|
||||||
gnc_numeric* val;
|
|
||||||
|
|
||||||
val = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (val, FALSE);
|
|
||||||
gncEmployeeSetWorkday (pdata->employee, *val);
|
|
||||||
g_free (val);
|
|
||||||
|
|
||||||
|
gncEmployeeSetWorkday (pdata->employee, dom_tree_to_gnc_numeric (node));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,13 +238,8 @@ static gboolean
|
|||||||
employee_rate_handler (xmlNodePtr node, gpointer employee_pdata)
|
employee_rate_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||||
{
|
{
|
||||||
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
|
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
|
||||||
gnc_numeric* val;
|
|
||||||
|
|
||||||
val = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (val, FALSE);
|
|
||||||
gncEmployeeSetRate (pdata->employee, *val);
|
|
||||||
g_free (val);
|
|
||||||
|
|
||||||
|
gncEmployeeSetRate (pdata->employee, dom_tree_to_gnc_numeric (node));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,11 +250,7 @@ static inline gboolean
|
|||||||
set_numeric (xmlNodePtr node, GncEntry* entry,
|
set_numeric (xmlNodePtr node, GncEntry* entry,
|
||||||
void (*func) (GncEntry* entry, gnc_numeric num))
|
void (*func) (GncEntry* entry, gnc_numeric num))
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
|
func (entry, dom_tree_to_gnc_numeric (node));
|
||||||
g_return_val_if_fail (num, FALSE);
|
|
||||||
|
|
||||||
func (entry, *num);
|
|
||||||
g_free (num);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,11 +382,8 @@ static gboolean
|
|||||||
invoice_tochargeamt_handler (xmlNodePtr node, gpointer invoice_pdata)
|
invoice_tochargeamt_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||||
{
|
{
|
||||||
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
|
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (num, FALSE);
|
|
||||||
|
|
||||||
gncInvoiceSetToChargeAmount (pdata->invoice, *num);
|
gncInvoiceSetToChargeAmount (pdata->invoice, dom_tree_to_gnc_numeric (node));
|
||||||
g_free (num);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +130,7 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
|
|||||||
}
|
}
|
||||||
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
|
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
|
||||||
{
|
{
|
||||||
gnc_numeric* value = dom_tree_to_gnc_numeric (sub_node);
|
gnc_price_set_value (p, dom_tree_to_gnc_numeric (sub_node));
|
||||||
if (!value) return FALSE;
|
|
||||||
gnc_price_set_value (p, *value);
|
|
||||||
g_free (value);
|
|
||||||
}
|
}
|
||||||
gnc_price_commit_edit (p);
|
gnc_price_commit_edit (p);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -183,11 +183,8 @@ static gboolean
|
|||||||
ttentry_amount_handler (xmlNodePtr node, gpointer ttentry_pdata)
|
ttentry_amount_handler (xmlNodePtr node, gpointer ttentry_pdata)
|
||||||
{
|
{
|
||||||
struct ttentry_pdata* pdata = static_cast<decltype (pdata)> (ttentry_pdata);
|
struct ttentry_pdata* pdata = static_cast<decltype (pdata)> (ttentry_pdata);
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
|
|
||||||
g_return_val_if_fail (num, FALSE);
|
|
||||||
|
|
||||||
gncTaxTableEntrySetAmount (pdata->ttentry, *num);
|
gncTaxTableEntrySetAmount (pdata->ttentry, dom_tree_to_gnc_numeric (node));
|
||||||
g_free (num);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,14 +217,8 @@ static inline gboolean
|
|||||||
set_spl_gnc_num (xmlNodePtr node, Split* spl,
|
set_spl_gnc_num (xmlNodePtr node, Split* spl,
|
||||||
void (*func) (Split* spl, gnc_numeric gn))
|
void (*func) (Split* spl, gnc_numeric gn))
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
|
func (spl, dom_tree_to_gnc_numeric (node));
|
||||||
g_return_val_if_fail (num, FALSE);
|
return TRUE;
|
||||||
|
|
||||||
func (spl, *num);
|
|
||||||
|
|
||||||
g_free (num);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -2967,10 +2967,7 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
|
|||||||
}
|
}
|
||||||
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
|
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
|
||||||
{
|
{
|
||||||
gnc_numeric* value = dom_tree_to_gnc_numeric (sub_node);
|
gnc_price_set_value (p, dom_tree_to_gnc_numeric (sub_node));
|
||||||
if (!value) return FALSE;
|
|
||||||
gnc_price_set_value (p, *value);
|
|
||||||
g_free (value);
|
|
||||||
}
|
}
|
||||||
gnc_price_commit_edit (p);
|
gnc_price_commit_edit (p);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -188,19 +188,7 @@ dom_tree_to_double_kvp_value (xmlNodePtr node)
|
|||||||
static KvpValue*
|
static KvpValue*
|
||||||
dom_tree_to_numeric_kvp_value (xmlNodePtr node)
|
dom_tree_to_numeric_kvp_value (xmlNodePtr node)
|
||||||
{
|
{
|
||||||
gnc_numeric* danum;
|
return new KvpValue {dom_tree_to_gnc_numeric (node)};
|
||||||
KvpValue* ret = NULL;
|
|
||||||
|
|
||||||
danum = dom_tree_to_gnc_numeric (node);
|
|
||||||
|
|
||||||
if (danum)
|
|
||||||
{
|
|
||||||
ret = new KvpValue {*danum};
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (danum);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static KvpValue*
|
static KvpValue*
|
||||||
@ -514,19 +502,19 @@ dom_tree_to_text (xmlNodePtr tree)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gnc_numeric*
|
gnc_numeric
|
||||||
dom_tree_to_gnc_numeric (xmlNodePtr node)
|
dom_tree_to_gnc_numeric (xmlNodePtr node)
|
||||||
{
|
{
|
||||||
gchar* content = dom_tree_to_text (node);
|
gchar* content = dom_tree_to_text (node);
|
||||||
if (!content)
|
if (!content)
|
||||||
return NULL;
|
return gnc_numeric_zero ();
|
||||||
|
|
||||||
gnc_numeric *ret = g_new (gnc_numeric, 1);
|
gnc_numeric num;
|
||||||
|
if (!string_to_gnc_numeric (content, &num))
|
||||||
|
num = gnc_numeric_zero ();
|
||||||
|
|
||||||
if (!string_to_gnc_numeric (content, ret))
|
|
||||||
*ret = gnc_numeric_zero ();
|
|
||||||
g_free (content);
|
g_free (content);
|
||||||
return ret;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ Recurrence* dom_tree_to_recurrence (xmlNodePtr node);
|
|||||||
time64 dom_tree_to_time64 (xmlNodePtr node);
|
time64 dom_tree_to_time64 (xmlNodePtr node);
|
||||||
gboolean dom_tree_valid_time64 (time64 ts, const xmlChar* name);
|
gboolean dom_tree_valid_time64 (time64 ts, const xmlChar* name);
|
||||||
GDate* dom_tree_to_gdate (xmlNodePtr node);
|
GDate* dom_tree_to_gdate (xmlNodePtr node);
|
||||||
gnc_numeric* dom_tree_to_gnc_numeric (xmlNodePtr node);
|
gnc_numeric dom_tree_to_gnc_numeric (xmlNodePtr node);
|
||||||
gchar* dom_tree_to_text (xmlNodePtr tree);
|
gchar* dom_tree_to_text (xmlNodePtr tree);
|
||||||
gboolean string_to_binary (const gchar* str, void** v, guint64* data_len);
|
gboolean string_to_binary (const gchar* str, void** v, guint64* data_len);
|
||||||
gboolean dom_tree_create_instance_slots (xmlNodePtr node, QofInstance* inst);
|
gboolean dom_tree_create_instance_slots (xmlNodePtr node, QofInstance* inst);
|
||||||
|
@ -163,7 +163,6 @@ static const char*
|
|||||||
test_gnc_nums_internal (gnc_numeric to_test)
|
test_gnc_nums_internal (gnc_numeric to_test)
|
||||||
{
|
{
|
||||||
const char* ret = NULL;
|
const char* ret = NULL;
|
||||||
gnc_numeric* to_compare = NULL;
|
|
||||||
xmlNodePtr to_gen = NULL;
|
xmlNodePtr to_gen = NULL;
|
||||||
|
|
||||||
to_gen = gnc_numeric_to_dom_tree ("test-num", &to_test);
|
to_gen = gnc_numeric_to_dom_tree ("test-num", &to_test);
|
||||||
@ -173,24 +172,13 @@ test_gnc_nums_internal (gnc_numeric to_test)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to_compare = dom_tree_to_gnc_numeric (to_gen);
|
gnc_numeric to_compare = dom_tree_to_gnc_numeric (to_gen);
|
||||||
if (!to_compare)
|
if (!gnc_numeric_equal (to_test, to_compare))
|
||||||
{
|
{
|
||||||
ret = "no gnc_numeric parsed";
|
ret = "numerics compared different";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!gnc_numeric_equal (to_test, *to_compare))
|
|
||||||
{
|
|
||||||
ret = "numerics compared different";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_compare)
|
|
||||||
{
|
|
||||||
g_free (to_compare);
|
|
||||||
}
|
|
||||||
if (to_gen)
|
if (to_gen)
|
||||||
{
|
{
|
||||||
xmlFreeNode (to_gen);
|
xmlFreeNode (to_gen);
|
||||||
|
@ -70,14 +70,12 @@ find_appropriate_node (xmlNodePtr node, Split* spl)
|
|||||||
{
|
{
|
||||||
if (g_strcmp0 ((char*)mark2->name, "split:value") == 0)
|
if (g_strcmp0 ((char*)mark2->name, "split:value") == 0)
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (mark2);
|
gnc_numeric num = dom_tree_to_gnc_numeric (mark2);
|
||||||
|
|
||||||
if (gnc_numeric_equal (*num, xaccSplitGetValue (spl)))
|
if (gnc_numeric_equal (num, xaccSplitGetValue (spl)))
|
||||||
{
|
{
|
||||||
amount_good = TRUE;
|
amount_good = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (num);
|
|
||||||
}
|
}
|
||||||
else if (g_strcmp0 ((char*)mark2->name, "split:account") == 0)
|
else if (g_strcmp0 ((char*)mark2->name, "split:account") == 0)
|
||||||
{
|
{
|
||||||
@ -143,44 +141,40 @@ equals_node_val_vs_split_internal (xmlNodePtr node, Split* spl)
|
|||||||
}
|
}
|
||||||
else if (g_strcmp0 ((char*)mark->name, "split:value") == 0)
|
else if (g_strcmp0 ((char*)mark->name, "split:value") == 0)
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (mark);
|
gnc_numeric num = dom_tree_to_gnc_numeric (mark);
|
||||||
gnc_numeric val = xaccSplitGetValue (spl);
|
gnc_numeric val = xaccSplitGetValue (spl);
|
||||||
|
|
||||||
if (!gnc_numeric_equal (*num, val))
|
if (!gnc_numeric_equal (num, val))
|
||||||
{
|
{
|
||||||
g_free (num);
|
|
||||||
return g_strdup_printf ("values differ: %" G_GINT64_FORMAT "/%"
|
return g_strdup_printf ("values differ: %" G_GINT64_FORMAT "/%"
|
||||||
G_GINT64_FORMAT " v %" G_GINT64_FORMAT
|
G_GINT64_FORMAT " v %" G_GINT64_FORMAT
|
||||||
"/%" G_GINT64_FORMAT,
|
"/%" G_GINT64_FORMAT,
|
||||||
(*num).num, (*num).denom,
|
num.num, num.denom,
|
||||||
val.num, val.denom);
|
val.num, val.denom);
|
||||||
}
|
}
|
||||||
g_free (num);
|
|
||||||
}
|
}
|
||||||
else if (g_strcmp0 ((char*)mark->name, "split:quantity") == 0)
|
else if (g_strcmp0 ((char*)mark->name, "split:quantity") == 0)
|
||||||
{
|
{
|
||||||
gnc_numeric* num = dom_tree_to_gnc_numeric (mark);
|
gnc_numeric num = dom_tree_to_gnc_numeric (mark);
|
||||||
gnc_numeric val = xaccSplitGetAmount (spl);
|
gnc_numeric val = xaccSplitGetAmount (spl);
|
||||||
|
|
||||||
if (!gnc_numeric_equal (*num, val))
|
if (!gnc_numeric_equal (num, val))
|
||||||
{
|
{
|
||||||
return g_strdup_printf ("quantities differ under _equal: %"
|
return g_strdup_printf ("quantities differ under _equal: %"
|
||||||
G_GINT64_FORMAT "/%" G_GINT64_FORMAT
|
G_GINT64_FORMAT "/%" G_GINT64_FORMAT
|
||||||
" v %" G_GINT64_FORMAT "/%"
|
" v %" G_GINT64_FORMAT "/%"
|
||||||
G_GINT64_FORMAT,
|
G_GINT64_FORMAT,
|
||||||
(*num).num, (*num).denom,
|
num.num, num.denom,
|
||||||
val.num, val.denom);
|
val.num, val.denom);
|
||||||
}
|
}
|
||||||
if (!gnc_numeric_equal (*num, val))
|
if (!gnc_numeric_equal (num, val))
|
||||||
{
|
{
|
||||||
g_free (num);
|
|
||||||
return g_strdup_printf ("quantities differ: %" G_GINT64_FORMAT
|
return g_strdup_printf ("quantities differ: %" G_GINT64_FORMAT
|
||||||
"/%" G_GINT64_FORMAT " v %"
|
"/%" G_GINT64_FORMAT " v %"
|
||||||
G_GINT64_FORMAT "/%" G_GINT64_FORMAT,
|
G_GINT64_FORMAT "/%" G_GINT64_FORMAT,
|
||||||
(*num).num, (*num).denom,
|
num.num, num.denom,
|
||||||
val.num, val.denom);
|
val.num, val.denom);
|
||||||
}
|
}
|
||||||
g_free (num);
|
|
||||||
}
|
}
|
||||||
else if (g_strcmp0 ((char*)mark->name, "split:account") == 0)
|
else if (g_strcmp0 ((char*)mark->name, "split:account") == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user