tree: account for ephemeral nevra string

When writing this code, I made the false assumption that the nevra
string lives as long as the pool does, i.e. as long as we have a
reference to its `DnfSack`.

In fact, they have undefined lifetimes. Notably any place in which one
calls `dnf_package_get_nevra` a lot may result in the invalidation of
previously returned nevras.

This patch ensures that we copy the string in the few places where we
are susceptible to this.

There is a related libdnf patch[1] which tightens the definition here so
that we can assume the string at least lives as long as its
`DnfPackage`. It turns out that the callsites addressed in this patch
are also those in which we would break that assumption. IOW, this patch
is needed regardless of how [1] goes.

[1] https://github.com/rpm-software-management/libdnf/pull/388

Closes: #1119
Approved by: cgwalters
This commit is contained in:
Jonathan Lebon 2017-11-29 17:57:41 +00:00 committed by Atomic Bot
parent 8f6f2dd9e4
commit 5860897092
2 changed files with 9 additions and 8 deletions

View File

@ -673,8 +673,9 @@ finalize_overlays (RpmOstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
/* request (owned by origin) --> providing nevra (owned by rsack) */
g_autoptr(GHashTable) inactive_requests = g_hash_table_new (g_str_hash, g_str_equal);
/* request (owned by origin) --> providing nevra */
g_autoptr(GHashTable) inactive_requests =
g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
g_autoptr(GPtrArray) ret_missing_pkgs = g_ptr_array_new_with_free_func (g_free);
/* Add the local pkgs as if they were installed: since they're unconditionally
@ -756,7 +757,8 @@ finalize_overlays (RpmOstreeSysrootUpgrader *self,
/* Otherwise, it's an inactive request: remember them so we can print a nice notice.
* Just use the first package as the "providing" pkg. */
const char *providing_nevra = dnf_package_get_nevra (matches->pdata[0]);
g_hash_table_insert (inactive_requests, (gpointer)pattern, (gpointer)providing_nevra);
g_hash_table_insert (inactive_requests, (gpointer)pattern,
g_strdup (providing_nevra));
}
if (g_hash_table_size (inactive_requests) > 0)

View File

@ -1496,8 +1496,7 @@ check_goal_solution (RpmOstreeContext *self,
{
HyGoal goal = dnf_context_get_goal (self->dnfctx);
/* all strings are owned by pool */
g_autoptr(GPtrArray) forbidden = g_ptr_array_new ();
g_autoptr(GPtrArray) forbidden = g_ptr_array_new_with_free_func (g_free);
g_assert (!self->pkgs_to_remove);
self->pkgs_to_remove = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
@ -1516,7 +1515,7 @@ check_goal_solution (RpmOstreeContext *self,
g_hash_table_insert (self->pkgs_to_remove, g_strdup (name),
gv_nevra_from_pkg (pkg));
else
g_ptr_array_add (forbidden, (gpointer)nevra);
g_ptr_array_add (forbidden, g_strdup (nevra));
}
if (forbidden->len > 0)
@ -1544,7 +1543,7 @@ check_goal_solution (RpmOstreeContext *self,
g_assert_cmpint (packages->len, ==, 0);
g_ptr_array_unref (forbidden);
forbidden = g_ptr_array_new ();
forbidden = g_ptr_array_new_with_free_func (g_free);
g_assert (!self->pkgs_to_replace);
self->pkgs_to_replace = g_hash_table_new_full (gv_nevra_hash, g_variant_equal,
@ -1572,7 +1571,7 @@ check_goal_solution (RpmOstreeContext *self,
g_hash_table_insert (self->pkgs_to_replace, gv_nevra_from_pkg (pkg),
gv_nevra_from_pkg (old_pkg));
else
g_ptr_array_add (forbidden, (gpointer)old_nevra);
g_ptr_array_add (forbidden, g_strdup (old_nevra));
}
if (forbidden->len > 0)