From a6ea97b9844c9b78c7e9b24c241fc16be22e4176 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sun, 13 Jun 2021 00:05:20 +0300 Subject: Skip/remove dangling implicit associations --- bpkg/package.cxx | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'bpkg/package.cxx') diff --git a/bpkg/package.cxx b/bpkg/package.cxx index b1e9ab1..abfcd55 100644 --- a/bpkg/package.cxx +++ b/bpkg/package.cxx @@ -497,12 +497,56 @@ namespace bpkg lazy_shared_ptr _selected_package_ref:: to_ptr (odb::database& db) && { + database& pdb (static_cast (db)); + // Note that if this points to a different configuration, then it should // already be pre-attached since it must be explicitly associated. // - return lazy_shared_ptr ( - static_cast (db).find_dependency_config (configuration), - move (prerequisite)); + database& ddb (pdb.find_dependency_config (configuration)); + + // Make sure the prerequisite exists in the explicitly associated + // configuration, so that a subsequent load() call will not fail. This, + // for example, can happen in unlikely but possible situation when the + // implicitly associated configuration containing a dependent was + // temporarily renamed before its prerequisite was dropped. + // + // Note that the diagnostics lacks information about the dependent and its + // configuration. However, handling this situation at all the load() + // function call sites where this information is available, for example by + // catching the odb::object_not_persistent exception, feels a bit + // hairy. Given the situation is not common, let's keep it simple for now + // and see how it goes. + // + // @@ As a side note, the following code crashes. Is this a libodb bug or + // just lack of my understanding? + // +#if 0 + if (ddb != pdb) + { + shared_ptr p ( + ddb.find (prerequisite)); + + if (p != nullptr) + { + lazy_shared_ptr lp (ddb, move (p)); + lp.database ().string (); // Ok. + + lazy_shared_ptr lp2 (move (lp)); + lp2.database ().string (); // Ok. + + lazy_shared_ptr lp3; + + lp3 = move (lp2); // lp2.i_.db_ is not copied (odb/lazy-ptr-impl.ixx:83) + lp3.database ().string (); // Crashes since lp3.i_.db_ is NULL. + } + } +#endif + + if (ddb != pdb && ddb.find (prerequisite) == nullptr) + fail << "unable to find prerequisite package " << prerequisite + << " in associated configuration " << ddb.config_orig; + + return lazy_shared_ptr (ddb, move (prerequisite)); } pair, database*> -- cgit v1.1