Skip to content

Commit

Permalink
Bug 799324 - Invalid free in gvalue_from_kvp_value()
Browse files Browse the repository at this point in the history
As of ddc3f28, gvalue_from_kvp_value()
takes a GValue pointer from the caller, which in some cases points to
memory on the stack.  If that is the case and the code also hits the
default case in the switch statement, the unconditional g_slice_free()
call will attempt to free stack memory, causing the program to abort.

Fix by requiring the caller to always pass in a valid GValue pointer,
making the caller responsible for freeing it if necessary.  This also
means that it is no longer necessary for gvalue_from_kvp_value() to
return a value, so make it a void function.
  • Loading branch information
living180 authored and jralls committed Jun 2, 2024
1 parent 5c716cc commit c4d44ea
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 13 deletions.
12 changes: 3 additions & 9 deletions libgnucash/engine/kvp-frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,11 @@ int compare(const KvpFrameImpl & one, const KvpFrameImpl & two) noexcept
return 0;
}

GValue*
void
gvalue_from_kvp_value (const KvpValue *kval, GValue* val)
{
if (kval == NULL) return NULL;
if (!val)
val = g_slice_new0 (GValue);
else
g_value_unset(val);
if (kval == NULL) return;
g_value_unset(val);

switch (kval->get_type())
{
Expand Down Expand Up @@ -274,11 +271,8 @@ gvalue_from_kvp_value (const KvpValue *kval, GValue* val)
default:
/* No transfer outside of QofInstance-derived classes! */
PWARN ("Error! Invalid attempt to transfer Kvp type %d", kval->get_type());
g_slice_free (GValue, val);
val = NULL;
break;
}
return val;
}

KvpValue*
Expand Down
4 changes: 2 additions & 2 deletions libgnucash/engine/kvp-value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ KvpValueImpl::set(T val) noexcept
/** @internal @{ */
/** Convert a kvp_value into a GValue. Frames aren't converted.
* @param kval: A KvpValue.
* @return GValue*. Must be freed with g_free().
* @param val: The GValue in which to store the converted value.
*/
GValue* gvalue_from_kvp_value (const KvpValue *kval, GValue* val = nullptr);
void gvalue_from_kvp_value (const KvpValue *kval, GValue* val);

/** Convert a gvalue into a kvpvalue.
* @param gval: A GValue of a type KvpValue can digest.
Expand Down
4 changes: 2 additions & 2 deletions libgnucash/engine/qofinstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,11 +1317,11 @@ static void
wrap_gvalue_function (const char* key, KvpValue *val, wrap_param & param)
{
GValue *gv;
gv = g_slice_new0 (GValue);
if (val->get_type() != KvpValue::Type::FRAME)
gv = gvalue_from_kvp_value(val);
gvalue_from_kvp_value(val, gv);
else
{
gv = g_slice_new0 (GValue);
g_value_init (gv, G_TYPE_STRING);
g_value_set_string (gv, nullptr);
}
Expand Down

0 comments on commit c4d44ea

Please sign in to comment.