diff --git a/bundles/event_admin/remote_provider/remote_provider_mqtt/src/celix_earpm_impl.c b/bundles/event_admin/remote_provider/remote_provider_mqtt/src/celix_earpm_impl.c index bf2f36a37..2d3e7763d 100644 --- a/bundles/event_admin/remote_provider/remote_provider_mqtt/src/celix_earpm_impl.c +++ b/bundles/event_admin/remote_provider/remote_provider_mqtt/src/celix_earpm_impl.c @@ -147,10 +147,12 @@ celix_event_admin_remote_provider_mqtt_t* celix_earpm_create(celix_bundle_contex return NULL; } - if (asprintf(&earpm->syncEventAckTopic, CELIX_EARPM_SYNC_EVENT_ACK_TOPIC_PREFIX"%s", earpm->fwUUID) < 0) { + earpm->syncEventAckTopic = NULL; + if (asprintf(&earpm->syncEventAckTopic, CELIX_EARPM_SYNC_EVENT_ACK_TOPIC_PREFIX "%s", earpm->fwUUID) < 0) { celix_logHelper_error(logHelper, "Failed to create sync event response topic."); return NULL; } + celix_autofree char* syncEventAckTopic = earpm->syncEventAckTopic; celix_status_t status = celixThreadMutex_create(&earpm->mutex, NULL); if (status != CELIX_SUCCESS) { diff --git a/bundles/http_admin/http_admin/src/activator.c b/bundles/http_admin/http_admin/src/activator.c index 6821bdd83..887a40711 100644 --- a/bundles/http_admin/http_admin/src/activator.c +++ b/bundles/http_admin/http_admin/src/activator.c @@ -49,7 +49,7 @@ static int http_admin_start(http_admin_activator_t *act, celix_bundle_context_t return CELIX_BUNDLE_EXCEPTION; } - char* httpRoot = NULL; + celix_autofree char* httpRoot = NULL; int rc = asprintf(&httpRoot, "%s/root", storeRoot); if (rc < 0) { celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot create http root directory for the http admin bundle."); @@ -61,7 +61,6 @@ static int http_admin_start(http_admin_activator_t *act, celix_bundle_context_t celix_status_t status = celix_utils_createDirectory(httpRoot, false, NULL); if (status != CELIX_SUCCESS) { celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot create http root directory for the http admin bundle."); - free(httpRoot); return status; } celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_DEBUG, "Using http root directory %s", httpRoot); @@ -97,7 +96,12 @@ static int http_admin_start(http_admin_activator_t *act, celix_bundle_context_t for(long port = prop_port_min; act->httpManager == NULL && port <= prop_port_max; port++) { char *port_str; - asprintf(&port_str, "%li", port); + rc= asprintf(&port_str, "%li", port); + if(rc < 0 || port_str == NULL) { + celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot allocate memory for port string."); + free(httpRoot); + return CELIX_ENOMEM; + } svr_opts[3] = port_str; act->httpManager = httpAdmin_create(ctx, httpRoot, svr_opts); free(port_str); diff --git a/bundles/http_admin/http_admin/src/http_admin.c b/bundles/http_admin/http_admin/src/http_admin.c index 7db8e1ea5..a7e2c89a7 100755 --- a/bundles/http_admin/http_admin/src/http_admin.c +++ b/bundles/http_admin/http_admin/src/http_admin.c @@ -418,6 +418,10 @@ static void createAliasesSymlink(const char *aliases, const char *admin_root, co } asprintf(&alias_path, "%s/%s%s", cwd, admin_root, sub_token); + if (alias_path == NULL) { // Check if asprintf failed. + continue; + } + if(aliasList_containsAlias(alias_list, alias_path)) { free(alias_path); continue; //Alias already existing, Continue to next entry @@ -431,6 +435,10 @@ static void createAliasesSymlink(const char *aliases, const char *admin_root, co } asprintf(&bnd_resource_path, "%s/%s/%s", cwd, bundle_root, sub_token); + if (bnd_resource_path == NULL) { // Check if asprintf failed. + free(alias_path); + continue; + } if(symlink(bnd_resource_path, alias_path) == 0) { http_alias_t *alias = calloc(1, sizeof(*alias)); diff --git a/bundles/http_admin/http_admin/src/service_tree.c b/bundles/http_admin/http_admin/src/service_tree.c index 7c5a9da7f..b5dd09f79 100644 --- a/bundles/http_admin/http_admin/src/service_tree.c +++ b/bundles/http_admin/http_admin/src/service_tree.c @@ -91,15 +91,23 @@ bool addServiceNode(service_tree_t *svc_tree, const char *uri, void *svc) { //Else root already exists } else if(svc_tree->root_node == NULL) { //No service yet added uri_cpy = strdup(uri); + if (uri_cpy == NULL) { // Check for memory allocation failure + return false; + } req_uri = strtok_r(uri_cpy, "/", &save_ptr); svc_tree->root_node = createServiceNode(NULL, NULL, NULL, NULL, req_uri, (tokenCount == 1 ? svc : NULL)); svc_tree->tree_node_count = 1; uri_exists = false; } else if(strcmp(svc_tree->root_node->svc_data->sub_uri, "root") == 0){ - asprintf(&uri_cpy, "%s%s", "root", uri); + if (asprintf(&uri_cpy, "%s%s", "root", uri)<0) { + return false; + } req_uri = strtok_r(uri_cpy, "/", &save_ptr); } else { uri_cpy = strdup(uri); + if (uri_cpy == NULL) { // Check for memory allocation failure + return false; + } req_uri = strtok_r(uri_cpy, "/", &save_ptr); } @@ -293,9 +301,15 @@ service_tree_node_t *findServiceNodeInTree(service_tree_t *svc_tree, const char if (tree_not_empty) { if(strcmp(current->svc_data->sub_uri, "root") == 0) { - asprintf(&uri_cpy, "%s%s", "root", uri); + if (asprintf(&uri_cpy, "%s%s", "root", uri)<0) + { + return NULL; + } } else { uri_cpy = strdup(uri); + if (uri_cpy == NULL) { // Check for strdup failure + return NULL; + } } char *uri_token = strtok_r(uri_cpy, "/", &save_ptr); diff --git a/bundles/logging/log_helper/src/celix_log_helper.c b/bundles/logging/log_helper/src/celix_log_helper.c index 8e58df954..6991c4adb 100644 --- a/bundles/logging/log_helper/src/celix_log_helper.c +++ b/bundles/logging/log_helper/src/celix_log_helper.c @@ -48,8 +48,15 @@ static void celix_logHelper_setLogSvc(void *handle, void *svc) { celix_log_helper_t* celix_logHelper_create(celix_bundle_context_t* ctx, const char* logServiceName) { celix_log_helper_t* logHelper = calloc(1, sizeof(*logHelper)); + if (logHelper == NULL) { + return NULL; + } logHelper->ctx = ctx; logHelper->logServiceName = celix_utils_strdup(logServiceName); + if (logHelper->logServiceName == NULL) { + free(logHelper); + return NULL; + } celixThreadMutex_create(&logHelper->mutex, NULL); const char *actLogLevelStr = celix_bundleContext_getProperty(ctx, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_DEFAULT_VALUE); @@ -58,7 +65,11 @@ celix_log_helper_t* celix_logHelper_create(celix_bundle_context_t* ctx, const ch char *filter = NULL; if (logServiceName != NULL) { - asprintf(&filter, "(%s=%s)", CELIX_LOG_SERVICE_PROPERTY_NAME, logServiceName); + if (asprintf(&filter, "(%s=%s)", CELIX_LOG_SERVICE_PROPERTY_NAME, logServiceName) < 0) { + free(logHelper->logServiceName); + free(logHelper); + return NULL; + } } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; diff --git a/bundles/remote_services/discovery_common/src/discovery_activator.c b/bundles/remote_services/discovery_common/src/discovery_activator.c index 0179c50f1..8c70cd6e7 100644 --- a/bundles/remote_services/discovery_common/src/discovery_activator.c +++ b/bundles/remote_services/discovery_common/src/discovery_activator.c @@ -104,14 +104,21 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context char* scope = NULL; int rc = asprintf(&scope, "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); - status = rc < 0 ? CELIX_ENOMEM : CELIX_SUCCESS; + if (rc < 0) { + return CELIX_ENOMEM; + } + status = rc < 0 ? CELIX_ENOMEM : CELIX_SUCCESS; celix_autoptr(celix_properties_t) props = NULL; if (status == CELIX_SUCCESS) { celix_logHelper_debug(activator->loghelper, "using scope %s.", scope); props = celix_properties_create(); - celix_properties_set(props, "DISCOVERY", "true"); + if (props==NULL) { + free(scope); + return CELIX_ENOMEM; + } + celix_properties_set(props, "DISCOVERY", "true"); celix_properties_set(props, (char *) CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); } @@ -126,17 +133,21 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context if (status == CELIX_SUCCESS) { endpoint_listener_t *endpointListener = calloc(1, sizeof(struct endpoint_listener)); - if (endpointListener) { - endpointListener->handle = activator->discovery; - endpointListener->endpointAdded = discovery_endpointAdded; - endpointListener->endpointRemoved = discovery_endpointRemoved; + if (endpointListener==NULL) { + free(scope); + status = CELIX_ENOMEM; + } + endpointListener->handle = activator->discovery; + endpointListener->endpointAdded = discovery_endpointAdded; + endpointListener->endpointRemoved = discovery_endpointRemoved; - status = bundleContext_registerService(context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, endpointListener, - celix_steal_ptr(props), &activator->endpointListenerService); + status = bundleContext_registerService(context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, endpointListener, + celix_steal_ptr(props), &activator->endpointListenerService); - if (status == CELIX_SUCCESS) { - activator->endpointListener = endpointListener; - } + if (status == CELIX_SUCCESS) { + activator->endpointListener = endpointListener; + } else{ + free(endpointListener); } } // We can release the scope, as celix_properties_set makes a copy of the key & value... diff --git a/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c b/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c index 4d6043cce..dab16971c 100644 --- a/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c +++ b/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c @@ -89,11 +89,13 @@ celix_status_t endpointDiscoveryServer_create(discovery_t *discovery, (*server)->loghelper = &discovery->loghelper; (*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL); if (!(*server)->entries) { + free(*server); return CELIX_ENOMEM; } status = celixThreadMutex_create(&(*server)->serverLock, NULL); if (status != CELIX_SUCCESS) { + free(*server); return CELIX_BUNDLE_EXCEPTION; } @@ -128,6 +130,11 @@ celix_status_t endpointDiscoveryServer_create(discovery_t *discovery, free(detectedIp); } + if (!(*server)->ip) { // Check if strdup failed + free(*server); + return CELIX_ENOMEM; + } + bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port); if (port == NULL) { port = defaultServerPort; @@ -148,6 +155,11 @@ celix_status_t endpointDiscoveryServer_create(discovery_t *discovery, } (*server)->path = format_path(path); + if (!(*server)->path) { + free((*server)->ip); + free(*server); + return CELIX_ENOMEM; + } const struct mg_callbacks callbacks = { .begin_request = endpointDiscoveryServer_callback, @@ -165,6 +177,13 @@ celix_status_t endpointDiscoveryServer_create(discovery_t *discovery, asprintf(&listeningPorts,"%s:%s", (*server)->ip, port); } + if (!listeningPorts) { // Check if asprintf failed + free((*server)->path); + free((*server)->ip); + free(*server); + return CELIX_ENOMEM; + } + const char *options[] = { "listening_ports", listeningPorts, "num_threads", DEFAULT_SERVER_THREADS, @@ -199,6 +218,12 @@ celix_status_t endpointDiscoveryServer_create(discovery_t *discovery, } while(((*server)->ctx == NULL) && (port_counter < max_ep_num)); (*server)->port = strdup(port); + if (!(*server)->port) { + free((*server)->path); + free((*server)->ip); + free(*server); + return CELIX_ENOMEM; + } return status; } diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 0c9acc360..78057aaf5 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -920,17 +920,11 @@ static int discoveryZeroConfWatcher_getHostIpAddresses(discovery_zeroconf_watche if (hostEntry != NULL) { CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { const char *ip = iter.key; - char *tmp= NULL; - if (ipAddressesStr == NULL) { - tmp = celix_utils_strdup(ip); - } else { - asprintf(&tmp, "%s,%s", ipAddressesStr, ip); - } + celix_autofree char *tmp = (ipAddressesStr == NULL) ? celix_utils_strdup(ip) : celix_utils_concat(ipAddressesStr, ",", ip); if (tmp == NULL) { return CELIX_ENOMEM; } - free(ipAddressesStr); - ipAddressesStr = tmp; + ipAddressesStr = celix_steal_ptr(tmp); } } if (ipAddressesStr == NULL) { diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c index ee4400c95..418c76289 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c @@ -195,7 +195,6 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote celix_status_t status = CELIX_SUCCESS; *admin = calloc(1, sizeof(**admin)); - if (!*admin) { status = CELIX_ENOMEM; } else { @@ -203,10 +202,10 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL); (*admin)->importedServices = celix_arrayList_create(); - celixThreadRwlock_create(&(*admin)->exportedServicesLock, NULL); - celixThreadMutex_create(&(*admin)->importedServicesLock, NULL); + celixThreadRwlock_create(&(*admin)->exportedServicesLock, NULL); + celixThreadMutex_create(&(*admin)->importedServicesLock, NULL); - (*admin)->importedEndpointUrls = celix_stringHashMap_create();//Ignore ENOMEM for now and deal with it on other PRs in the future + (*admin)->importedEndpointUrls = celix_stringHashMap_create(); // Ignore ENOMEM for now (*admin)->loghelper = celix_logHelper_create(context, "celix_rsa_admin"); @@ -214,7 +213,6 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote const char *ip = celix_bundleContext_getProperty(context, RSA_IP_KEY, RSA_IP_DEFAULT); const char *interface = celix_bundleContext_getProperty(context, RSA_INTERFACE_KEY, NULL); (*admin)->curlShareEnabled = celix_bundleContext_getPropertyAsBool(context, RSA_DFI_USE_CURL_SHARE_HANDLE, RSA_DFI_USE_CURL_SHARE_HANDLE_DEFAULT); - (*admin)->dynamicIpSupport = celix_bundleContext_getPropertyAsBool(context, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT_DEFAULT); char *detectedIp = NULL; @@ -231,6 +229,9 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote if (ip != NULL) { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_DEBUG, "RSA: Using %s for service annunciation", ip); (*admin)->ip = strdup(ip); + } else { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_WARNING, "RSA: No IP address found, using default: %s", RSA_IP_DEFAULT); + (*admin)->ip = strdup(RSA_IP_DEFAULT); } if (detectedIp != NULL) { @@ -238,32 +239,37 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote } (*admin)->curlShare = curl_share_init(); - curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); - curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); - curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); - curl_share_setopt((*admin)->curlShare, CURLSHOPT_USERDATA, *admin); - - curl_share_setopt((*admin)->curlShare, CURLSHOPT_LOCKFUNC, remoteServiceAdmin_curlshare_lock); - curl_share_setopt((*admin)->curlShare, CURLSHOPT_UNLOCKFUNC, remoteServiceAdmin_curlshare_unlock); + if ((*admin)->curlShare == NULL) { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, "Failed to initialize cURL share handle."); + status = CELIX_BUNDLE_EXCEPTION; + } else { + curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); + curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); + curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + curl_share_setopt((*admin)->curlShare, CURLSHOPT_USERDATA, *admin); + curl_share_setopt((*admin)->curlShare, CURLSHOPT_LOCKFUNC, remoteServiceAdmin_curlshare_lock); + curl_share_setopt((*admin)->curlShare, CURLSHOPT_UNLOCKFUNC, remoteServiceAdmin_curlshare_unlock); + } - if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexConnect, NULL) != 0) { - fprintf(stderr, "Could not initialize mutex connect\n"); - status = EPERM; + if (status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexConnect, NULL) != 0) { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, "Could not initialize mutex connect"); + status = CELIX_BUNDLE_EXCEPTION; } - if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexCookie, NULL) != 0) { - fprintf(stderr, "Could not initialize mutex cookie\n"); - status = EPERM; + if (status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexCookie, NULL) != 0) { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, "Could not initialize mutex cookie"); + status = CELIX_BUNDLE_EXCEPTION; } - if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexDns, NULL) != 0) { - fprintf(stderr, "Could not initialize mutex dns\n"); - status = EPERM; + if (status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexDns, NULL) != 0) { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, "Could not initialize mutex dns"); + status = CELIX_BUNDLE_EXCEPTION; } - remoteServiceAdmin_setupStopExportsThread(*admin); + if (status == CELIX_SUCCESS) { + remoteServiceAdmin_setupStopExportsThread(*admin); + } - // Prepare callbacks structure. We have only one callback, the rest are NULL. struct mg_callbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); callbacks.begin_request = remoteServiceAdmin_callback; @@ -273,30 +279,42 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote unsigned int port_counter = 0; bool bindToAllInterfaces = celix_bundleContext_getPropertyAsBool(context, CELIX_RSA_BIND_ON_ALL_INTERFACES, CELIX_RSA_BIND_ON_ALL_INTERFACES_DEFAULT); + do { char *listeningPorts = NULL; - if (bindToAllInterfaces || (*admin)->dynamicIpSupport) { - asprintf(&listeningPorts,"0.0.0.0:%s", newPort); + if ((*admin)->dynamicIpSupport || bindToAllInterfaces) { + asprintf(&listeningPorts, "0.0.0.0:%s", newPort); } else { - asprintf(&listeningPorts,"%s:%s", (*admin)->ip, newPort); + asprintf(&listeningPorts, "%s:%s", (*admin)->ip, newPort); } - const char *options[] = { "listening_ports", listeningPorts, "num_threads", "5", NULL}; + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_INFO, + "Binding webserver using IP: %s, Port: %s, Dynamic IP Support: %s, Bind To All Interfaces: %s", + (*admin)->ip ? (*admin)->ip : "0.0.0.0", newPort, + (*admin)->dynamicIpSupport ? "Enabled" : "Disabled", + bindToAllInterfaces ? "Enabled" : "Disabled"); + + const char *options[] = { "listening_ports", listeningPorts, "num_threads", "5", NULL }; (*admin)->ctx = mg_start(&callbacks, (*admin), options); if ((*admin)->ctx != NULL) { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_INFO, "RSA: Start webserver: %s", listeningPorts); (*admin)->port = strdup(newPort); - } else { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, "Error while starting rsa server on port %s - retrying on port %li...", newPort, port + port_counter); - snprintf(newPort, 10, "%li", port + port_counter++); + snprintf(newPort, 10, "%li", port + port_counter++); } free(listeningPorts); } while (((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS)); + + if ((*admin)->ctx == NULL && port_counter >= MAX_NUMBER_OF_RESTARTS) { + celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_ERROR, + "Failed to start RSA server after %d retries. Last attempted port: %s", MAX_NUMBER_OF_RESTARTS, newPort); + status = CELIX_BUNDLE_EXCEPTION; + } } bool logCalls = celix_bundleContext_getPropertyAsBool(context, RSA_LOG_CALLS_KEY, RSA_LOG_CALLS_DEFAULT); @@ -306,12 +324,26 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote (*admin)->logFile = stdout; } else { (*admin)->logFile = fopen(f, "w"); - if ( (*admin)->logFile == NULL) { + if ((*admin)->logFile == NULL) { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_WARNING, "Error opening file '%s' for logging calls. %s", f, strerror(errno)); } } } + if (status != CELIX_SUCCESS) { + // Cleanup on failure + if (*admin) { + celix_arrayList_destroy((*admin)->importedServices); + celix_stringHashMap_destroy((*admin)->importedEndpointUrls); + celix_logHelper_destroy((*admin)->loghelper); + if ((*admin)->curlShare) { + curl_share_cleanup((*admin)->curlShare); + } + free(*admin); + *admin = NULL; + } + } + return status; } diff --git a/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c b/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c index 5a8029ae2..8967d2baa 100644 --- a/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c +++ b/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c @@ -79,6 +79,10 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context celix_properties_t *props = NULL; if (status == CELIX_SUCCESS) { props = celix_properties_create(); + if (!props) { + free(scope); + return CELIX_ENOMEM; + } celix_properties_set(props, "DISCOVERY", "true"); celix_properties_set(props, (char *) CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); } @@ -86,7 +90,9 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context if (status == CELIX_SUCCESS) { endpoint_listener_t *endpointListener = calloc(1, sizeof(struct endpoint_listener)); - if (endpointListener) { + if (!endpointListener) { + status = CELIX_ENOMEM; + } else { endpointListener->handle = act; endpointListener->endpointAdded = discovery_endpointAdded; endpointListener->endpointRemoved = discovery_endpointRemoved; @@ -105,8 +111,9 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context // We can release the scope, as celix_properties_set makes a copy of the key & value... free(scope); - //if properties are not used in service registration, destroy it. - celix_properties_destroy(props); + if (props) { + celix_properties_destroy(props); + } return status; } diff --git a/libs/framework/src/bundle.c b/libs/framework/src/bundle.c index 054b9bd56..27cb7d463 100644 --- a/libs/framework/src/bundle.c +++ b/libs/framework/src/bundle.c @@ -304,16 +304,25 @@ static char* celix_bundle_getBundleOrPersistentStoreEntry(const celix_bundle_t* root = celix_bundleArchive_getPersistentStoreRoot(archive); } + if (root == NULL) { + fw_logCode(bnd->framework->logger, CELIX_BUNDLE_EXCEPTION, CELIX_ILLEGAL_STATE, "Failed to get valid root directory"); + return NULL; + } + char *entry = NULL; - if (name == NULL || strnlen(name, 1) == 0) { //NULL or "" + if (name == NULL || strnlen(name, 1) == 0) { // NULL or "" entry = celix_utils_strdup(root); } else if ((strnlen(name, 1) > 0) && (name[0] == '/')) { - asprintf(&entry, "%s%s", root, name); + if (asprintf(&entry, "%s%s", root, name) < 0) { + return NULL; // Memory allocation failure + } } else { - asprintf(&entry, "%s/%s", root, name); + if (asprintf(&entry, "%s/%s", root, name) < 0) { + return NULL; // Memory allocation failure + } } - if (celix_utils_fileExists(entry)) { + if (entry && celix_utils_fileExists(entry)) { return entry; } else { free(entry); @@ -321,6 +330,7 @@ static char* celix_bundle_getBundleOrPersistentStoreEntry(const celix_bundle_t* } } + char* celix_bundle_getEntry(const celix_bundle_t* bnd, const char *path) { char *entry = NULL; if (bnd != NULL && bnd->framework != NULL) { diff --git a/libs/framework/src/celix_bundle_cache.c b/libs/framework/src/celix_bundle_cache.c index d401ac432..63dad2e40 100644 --- a/libs/framework/src/celix_bundle_cache.c +++ b/libs/framework/src/celix_bundle_cache.c @@ -104,32 +104,38 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach if (NULL == cache->locationToBundleIdLookupMap) { return CELIX_ENOMEM; } - celixThreadMutex_create(&cache->mutex, NULL); - celix_autoptr(celix_thread_mutex_t) mutex = &cache->mutex; + status = celixThreadMutex_create(&cache->mutex, NULL); + if (status != CELIX_SUCCESS) { + return status; // Mutex creation failed, return the error code + } if (useTmpDir) { - //Using /tmp dir for cache, so that multiple frameworks can be launched - //instead of cacheDir = ".cache"; const char* pg = bundleCache_progamName(); if (pg == NULL) { pg = ""; } - asprintf(&cache->cacheDir, "/tmp/celix-cache-%s-%s", pg, celix_framework_getUUID(fw)); + if (asprintf(&cache->cacheDir, "/tmp/celix-cache-%s-%s", pg, celix_framework_getUUID(fw)) < 0) { + return CELIX_ENOMEM; // asprintf failure + } } else { const char* cacheDir = celix_bundleCache_cacheDirPath(fw); cache->cacheDir = celix_utils_strdup(cacheDir); } + if (NULL == cache->cacheDir) { return CELIX_ENOMEM; } + celix_autofree char* cacheDir = cache->cacheDir; if (cache->deleteOnCreate) { status = celix_bundleCache_deleteCacheDir(cache); if (status != CELIX_SUCCESS) { + fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Error deleting cache directory: %s", cache->cacheDir); return status; } } + const char* errorStr; status = celix_utils_createDirectory(cache->cacheDir, false, &errorStr); if (status != CELIX_SUCCESS) { @@ -137,14 +143,15 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach cache->cacheDir, errorStr); return status; } + cache->locationToBundleIdLookupMapLoaded = false; - celix_steal_ptr(cacheDir); - celix_steal_ptr(mutex); - celix_steal_ptr(locationToBundleIdLookupMap); - *out = celix_steal_ptr(cache); + + *out = cache; // Cache is returned, no need to steal pointers here. + return CELIX_SUCCESS; } + celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t* cache) { celix_status_t status = CELIX_SUCCESS; if (cache->deleteOnDestroy) { diff --git a/libs/framework/src/service_registry.c b/libs/framework/src/service_registry.c index b7e8e7dd7..6835215a8 100644 --- a/libs/framework/src/service_registry.c +++ b/libs/framework/src/service_registry.c @@ -816,33 +816,50 @@ char* celix_serviceRegistry_createFilterFor(celix_service_registry_t* registry, celix_autofree char* versionRange = NULL; if (versionRangeStr != NULL) { celix_autoptr(celix_version_range_t) range = celix_versionRange_parse(versionRangeStr); - if(range == NULL) { + if (range == NULL) { celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, - "Error incorrect version range."); + "Error: incorrect version range."); return NULL; } versionRange = celix_versionRange_createLDAPFilter(range, CELIX_FRAMEWORK_SERVICE_VERSION); if (versionRange == NULL) { celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, - "Error creating LDAP filter."); + "Error: creating LDAP filter."); return NULL; } } - //setting filter + // Setting filter if (additionalFilterIn != NULL && versionRange != NULL) { - asprintf(&filter, "(&(%s=%s)%s%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, versionRange, additionalFilterIn); + if (asprintf(&filter, "(&(%s=%s)%s%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, versionRange, additionalFilterIn) < 0) { + celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, + "Error: asprintf failed while constructing filter with serviceName '%s'.", serviceName); + return NULL; + } } else if (versionRange != NULL) { - asprintf(&filter, "(&(%s=%s)%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, versionRange); + if (asprintf(&filter, "(&(%s=%s)%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, versionRange) < 0) { + celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, + "Error: asprintf failed while constructing filter with serviceName '%s'.", serviceName); + return NULL; + } } else if (additionalFilterIn != NULL) { - asprintf(&filter, "(&(%s=%s)%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, additionalFilterIn); + if (asprintf(&filter, "(&(%s=%s)%s)", CELIX_FRAMEWORK_SERVICE_NAME, serviceName, additionalFilterIn) < 0) { + celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, + "Error: asprintf failed while constructing filter with serviceName '%s'.", serviceName); + return NULL; + } } else { - asprintf(&filter, "(&(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, serviceName); + if (asprintf(&filter, "(&(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, serviceName) < 0) { + celix_framework_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__, + "Error: asprintf failed while constructing filter with serviceName '%s'.", serviceName); + return NULL; + } } return filter; } + static int celix_serviceRegistry_compareRegistrations(celix_array_list_entry_t a, celix_array_list_entry_t b) { const service_registration_t* regA = a.voidPtrVal; const service_registration_t* regB = b.voidPtrVal; diff --git a/libs/framework/src/service_tracker.c b/libs/framework/src/service_tracker.c index d24d8198b..071d0c430 100644 --- a/libs/framework/src/service_tracker.c +++ b/libs/framework/src/service_tracker.c @@ -90,22 +90,28 @@ static inline void tracked_waitAndDestroy(celix_tracked_entry_t *tracked) { } celix_status_t serviceTracker_create(bundle_context_pt context, const char * service, service_tracker_customizer_pt customizer, service_tracker_pt *tracker) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - if (service == NULL || *tracker != NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { + if (service == NULL || *tracker != NULL) { + status = CELIX_ILLEGAL_ARGUMENT; + } else { char *filter = NULL; - asprintf(&filter, "(%s=%s)", CELIX_FRAMEWORK_SERVICE_NAME, service); - serviceTracker_createWithFilter(context, filter, customizer, tracker); - free(filter); - } + // Check for failure in asprintf + if (asprintf(&filter, "(%s=%s)", CELIX_FRAMEWORK_SERVICE_NAME, service) < 0) { + status = CELIX_ENOMEM; // Memory allocation failure + } else { + status = serviceTracker_createWithFilter(context, filter, customizer, tracker); + free(filter); + } + } - framework_logIfError(context->framework->logger, status, NULL, "Cannot create service tracker"); + // Log the error if status is not success + framework_logIfError(context->framework->logger, status, NULL, "Cannot create service tracker"); - return status; + return status; } + celix_status_t serviceTracker_createWithFilter(bundle_context_pt context, const char * filter, service_tracker_customizer_pt customizer, service_tracker_pt *out) { service_tracker_t* tracker = calloc(1, sizeof(*tracker)); *out = tracker; diff --git a/libs/utils/src/properties.c b/libs/utils/src/properties.c index f48c1eb31..9e6bce2e5 100644 --- a/libs/utils/src/properties.c +++ b/libs/utils/src/properties.c @@ -119,6 +119,7 @@ static celix_status_t celix_properties_fillEntry(celix_properties_t* properties, char convertedValueBuffer[21] = {0}; memcpy(entry, prototype, sizeof(*entry)); entry->value = NULL; + if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION) { bool written = celix_version_fillString(entry->typed.versionValue, convertedValueBuffer, sizeof(convertedValueBuffer)); @@ -137,7 +138,9 @@ static celix_status_t celix_properties_fillEntry(celix_properties_t* properties, entry->value = celix_properties_createString(properties, convertedValueBuffer); } else { char* val = NULL; - asprintf(&val, "%f", entry->typed.doubleValue); + if (asprintf(&val, "%f", entry->typed.doubleValue) < 0) { + return CELIX_ENOMEM; // Handle asprintf failure + } entry->value = val; } } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL) { @@ -152,6 +155,7 @@ static celix_status_t celix_properties_fillEntry(celix_properties_t* properties, if (entry->value == NULL) { return CELIX_ENOMEM; } + return CELIX_SUCCESS; } diff --git a/libs/utils/src/version.c b/libs/utils/src/version.c index 0ef56d528..8d569c43f 100644 --- a/libs/utils/src/version.c +++ b/libs/utils/src/version.c @@ -211,7 +211,7 @@ int celix_version_compareTo(const celix_version_t* version, const celix_version_ char* celix_version_toString(const celix_version_t* version) { char* string = NULL; int rc; - if (strlen(version->qualifier) > 0) { + if (version->qualifier != NULL && strlen(version->qualifier) > 0) { rc = asprintf(&string,"%d.%d.%d.%s", version->major, version->minor, version->micro, version->qualifier); } else { rc = asprintf(&string, "%d.%d.%d", version->major, version->minor, version->micro); diff --git a/libs/utils/src/version_range.c b/libs/utils/src/version_range.c index 08e5d9c5d..bba9649a7 100644 --- a/libs/utils/src/version_range.c +++ b/libs/utils/src/version_range.c @@ -146,24 +146,49 @@ char* celix_versionRange_createLDAPFilter(const celix_version_range_t* range, co char *output = NULL; int ret = -1; - if(range->high == NULL) { - ret = asprintf(&output, "(&(%s%s%i.%i.%i%s%s))", - serviceVersionAttributeName, range->isLowInclusive ? ">=" : ">", range->low->major, - range->low->minor, range->low->micro, - range->low->qualifier ? "." : "", - range->low->qualifier ? range->low->qualifier : ""); + + char* formatVersion(const celix_version_t* version) { + char* versionStr = NULL; + if (version != NULL) { + ret = asprintf(&versionStr, "%i.%i.%i%s%s", version->major, version->minor, version->micro, + version->qualifier ? "." : "", version->qualifier ? version->qualifier : ""); + if (ret < 0) { + return NULL; // Return NULL if asprintf fails + } + } + return versionStr; + } + + // If there is no high version, just use low version for the filter + if (range->high == NULL) { + char* lowVersion = formatVersion(range->low); + if (lowVersion == NULL) { + return NULL; // Return NULL if version formatting fails + } + + ret = asprintf(&output, "(&(%s%s%s))", + serviceVersionAttributeName, range->isLowInclusive ? ">=" : ">", lowVersion); + free(lowVersion); // Free the low version string after use } else { - ret = asprintf(&output, "(&(%s%s%i.%i.%i%s%s)(%s%s%i.%i.%i%s%s))", - serviceVersionAttributeName, range->isLowInclusive ? ">=" : ">", range->low->major, - range->low->minor, range->low->micro, - range->low->qualifier ? "." : "", - range->low->qualifier ? range->low->qualifier : "", - serviceVersionAttributeName, range->isHighInclusive ? "<=" : "<", range->high->major, - range->high->minor, range->high->micro, - range->high->qualifier ? "." : "", - range->high->qualifier ? range->high->qualifier : ""); + char* lowVersion = formatVersion(range->low); + char* highVersion = formatVersion(range->high); + if (lowVersion == NULL || highVersion == NULL) { + free(lowVersion); // Clean up allocated memory if formatting failed + free(highVersion); + return NULL; + } + + ret = asprintf(&output, "(&(%s%s%s)(%s%s%s))", + serviceVersionAttributeName, range->isLowInclusive ? ">=" : ">", + lowVersion, + serviceVersionAttributeName, range->isHighInclusive ? "<=" : "<", + highVersion); + + free(lowVersion); // Free the version strings after use + free(highVersion); } + // Return NULL if asprintf failed if (ret < 0) { return NULL; } @@ -171,6 +196,7 @@ char* celix_versionRange_createLDAPFilter(const celix_version_range_t* range, co return output; } + bool celix_versionRange_createLDAPFilterInPlace(const celix_version_range_t* range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength) { if(buffer == NULL || bufferLength == 0 || range->low == NULL) { return false;