Skip to content

Commit

Permalink
Fixes #653, Ensure that any BundleContext functions do not segfault i…
Browse files Browse the repository at this point in the history
…f the bundle context is invalid (#656)

Signed-off-by: The MathWorks, Inc. <alchrist@mathworks.com>
  • Loading branch information
achristoforides committed Apr 12, 2022
1 parent fe1d025 commit a240213
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 1 deletion.
7 changes: 6 additions & 1 deletion framework/include/cppmicroservices/BundleContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class US_Framework_EXPORT BundleContext
* the Framework properties, the method returns an empty \c Any.
*
* @param key The name of the requested property.
* @throws std::runtime_error If this BundleContext is no longer valid.
* @return The value of the requested property, or an empty \c Any if the
* property is undefined.
*/
Expand All @@ -188,6 +189,7 @@ class US_Framework_EXPORT BundleContext
/**
* Returns all known properties.
*
* @throws std::runtime_error If this BundleContext is no longer valid.
* @return A map of all framework properties.
*/
AnyMap GetProperties() const;
Expand Down Expand Up @@ -445,7 +447,7 @@ class US_Framework_EXPORT BundleContext
* search.
* @throws std::invalid_argument If the specified <code>filter</code>
* contains an invalid filter expression that cannot be parsed.
* @throws std::logic_error If this BundleContext is no longer valid.
* @throws std::runtime_error If this BundleContext is no longer valid.
* @throws ServiceException If the service interface id of \c S is empty, see @ref gr_serviceinterface.
*
* @see GetServiceReferences(const std::string&, const std::string&)
Expand Down Expand Up @@ -641,6 +643,9 @@ class US_Framework_EXPORT BundleContext
template<class S>
ServiceObjects<S> GetServiceObjects(const ServiceReference<S>& reference)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}
return ServiceObjects<S>(d, reference);
}

Expand Down
100 changes: 100 additions & 0 deletions framework/src/bundle/BundleContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,20 @@ BundleContext& BundleContext::operator=(std::nullptr_t)

std::shared_ptr<detail::LogSink> BundleContext::GetLogSink() const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
return d->bundle->coreCtx->sink->shared_from_this();
}

Any BundleContext::GetProperty(const std::string& key) const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -94,6 +102,10 @@ Any BundleContext::GetProperty(const std::string& key) const

AnyMap BundleContext::GetProperties() const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -107,6 +119,10 @@ AnyMap BundleContext::GetProperties() const

Bundle BundleContext::GetBundle() const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -120,6 +136,10 @@ Bundle BundleContext::GetBundle() const

Bundle BundleContext::GetBundle(long id) const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -134,6 +154,10 @@ Bundle BundleContext::GetBundle(long id) const

std::vector<Bundle> BundleContext::GetBundles(const std::string& location) const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -151,6 +175,10 @@ std::vector<Bundle> BundleContext::GetBundles(const std::string& location) const

std::vector<Bundle> BundleContext::GetBundles() const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -171,6 +199,10 @@ ServiceRegistrationU BundleContext::RegisterService(
const InterfaceMapConstPtr& service,
const ServiceProperties& properties)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -186,6 +218,10 @@ std::vector<ServiceReferenceU> BundleContext::GetServiceReferences(
const std::string& clazz,
const std::string& filter)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -201,6 +237,10 @@ std::vector<ServiceReferenceU> BundleContext::GetServiceReferences(

ServiceReferenceU BundleContext::GetServiceReference(const std::string& clazz)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand Down Expand Up @@ -263,6 +303,10 @@ std::shared_ptr<void> BundleContext::GetService(
"valid input to GetService()");
}

if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -284,6 +328,10 @@ InterfaceMapConstPtr BundleContext::GetService(
"valid input to GetService()");
}

if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -301,6 +349,10 @@ InterfaceMapConstPtr BundleContext::GetService(
ListenerToken BundleContext::AddServiceListener(const ServiceListener& delegate,
const std::string& filter)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -314,6 +366,10 @@ ListenerToken BundleContext::AddServiceListener(const ServiceListener& delegate,

void BundleContext::RemoveServiceListener(const ServiceListener& delegate)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -328,6 +384,10 @@ void BundleContext::RemoveServiceListener(const ServiceListener& delegate)

ListenerToken BundleContext::AddBundleListener(const BundleListener& delegate)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -341,6 +401,10 @@ ListenerToken BundleContext::AddBundleListener(const BundleListener& delegate)

void BundleContext::RemoveBundleListener(const BundleListener& delegate)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -355,6 +419,10 @@ void BundleContext::RemoveBundleListener(const BundleListener& delegate)
ListenerToken BundleContext::AddFrameworkListener(
const FrameworkListener& listener)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -368,6 +436,10 @@ ListenerToken BundleContext::AddFrameworkListener(

void BundleContext::RemoveFrameworkListener(const FrameworkListener& listener)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -383,6 +455,10 @@ ListenerToken BundleContext::AddServiceListener(const ServiceListener& delegate,
void* data,
const std::string& filter)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -397,6 +473,10 @@ ListenerToken BundleContext::AddServiceListener(const ServiceListener& delegate,
void BundleContext::RemoveServiceListener(const ServiceListener& delegate,
void* data)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -412,6 +492,10 @@ void BundleContext::RemoveServiceListener(const ServiceListener& delegate,
ListenerToken BundleContext::AddBundleListener(const BundleListener& delegate,
void* data)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -426,6 +510,10 @@ ListenerToken BundleContext::AddBundleListener(const BundleListener& delegate,
void BundleContext::RemoveBundleListener(const BundleListener& delegate,
void* data)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -439,6 +527,10 @@ void BundleContext::RemoveBundleListener(const BundleListener& delegate,

void BundleContext::RemoveListener(ListenerToken token)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -452,6 +544,10 @@ void BundleContext::RemoveListener(ListenerToken token)

std::string BundleContext::GetDataFile(const std::string& filename) const
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);

Expand All @@ -474,6 +570,10 @@ std::vector<Bundle> BundleContext::InstallBundles(
const std::string& location,
const cppmicroservices::AnyMap& bundleManifest)
{
if (!d) {
throw std::runtime_error("The bundle context is no longer valid");
}

d->CheckValid();
auto b = (d->Lock(), d->bundle);
// CONCURRENCY NOTE: This is a check-then-act situation,
Expand Down

0 comments on commit a240213

Please sign in to comment.