From d8e9c66101f77c951f0af74078b96739dc2bf52a Mon Sep 17 00:00:00 2001 From: Sidhanth B H Date: Mon, 12 Jan 2026 15:41:52 +0530 Subject: [PATCH] RDKEMW-12252: Coverity Scan Report - Analyzing and Fixing all the Critical and High issues Reason for change: Resolve Critical and high level issues in coverity Test Procedure: build should be successful Risk: low Priority: P2 --- include/IJavaScriptContext.h | 1 + include/JSRuntimeClient.h | 14 +++++-- src/JSRuntimeClient.cpp | 62 ++++++++++++++++------------ src/JSRuntimeClientContainer.cpp | 46 +++++++++++++-------- src/JSRuntimeServer.cpp | 1 + src/NativeJSRenderer.cpp | 70 ++++++++++++++++++++------------ src/jsc/JavaScriptContext.cpp | 9 +++- src/jsc/JavaScriptEngine.cpp | 2 +- src/jsc/JavaScriptUtils.cpp | 48 +++++++++++++++++++--- src/jsc/jsc_lib/jsc_lib.cpp | 42 ++++++++++++------- src/jsruntime.cpp | 24 +++++++---- 11 files changed, 217 insertions(+), 102 deletions(-) diff --git a/include/IJavaScriptContext.h b/include/IJavaScriptContext.h index 7c5ca76..6f33ec6 100644 --- a/include/IJavaScriptContext.h +++ b/include/IJavaScriptContext.h @@ -25,6 +25,7 @@ class IJavaScriptContext { public: + virtual ~IJavaScriptContext() = default; virtual bool runScript(const char *script, bool isModule=true, std::string name="", const char *args = nullptr, bool isApplication=false) = 0; virtual bool runFile(const char *file, const char* args, bool isApplication=false) = 0; virtual std::string getUrl() = 0; diff --git a/include/JSRuntimeClient.h b/include/JSRuntimeClient.h index a34588a..8dfea4c 100644 --- a/include/JSRuntimeClient.h +++ b/include/JSRuntimeClient.h @@ -48,9 +48,15 @@ class CommandInterface if (derived.send(command)) { std::unique_lock lock(mResponseMutex); - mResponseCondition.wait_for(lock, std::chrono::seconds(5)); - response = mLastResponse; - return true; + mResponseReceived = false; + bool gotResponse = mResponseCondition.wait_for(lock, std::chrono::seconds(5), + [this]() { return mResponseReceived; }); + + if (gotResponse) + { + response = mLastResponse; + return true; + } } return false; @@ -63,6 +69,7 @@ class CommandInterface { std::lock_guard lock(mResponseMutex); mLastResponse = message; + mResponseReceived = true; mResponseCondition.notify_one(); } @@ -71,6 +78,7 @@ class CommandInterface CommandInterface &operator=(const CommandInterface &) = delete; std::string mLastResponse; + bool mResponseReceived = false; std::mutex mResponseMutex; std::condition_variable mResponseCondition; }; diff --git a/src/JSRuntimeClient.cpp b/src/JSRuntimeClient.cpp index 65e4c73..173282b 100644 --- a/src/JSRuntimeClient.cpp +++ b/src/JSRuntimeClient.cpp @@ -76,7 +76,9 @@ bool JSRuntimeClient::run() t.detach(); std::unique_lock lock(mStateMutex); - mStateCondition.wait_for(lock, std::chrono::seconds(5)); + mStateCondition.wait_for(lock, std::chrono::seconds(5), [this]() { + return mState != "none"; + }); return mState == "open"; } @@ -152,37 +154,45 @@ void JSRuntimeClient::onClose(websocketpp::connection_hdl hdl) #ifndef UNIT_TEST_BUILD int main(int argc, char **argv) { - std::string command; - std::string response; + try { + std::string command; + std::string response; - if (argc > 1) - { - NativeJSLogger::log(INFO, "Send input commands at ws://localhost:%s\n", std::to_string(WS_SERVER_PORT).c_str()); - return -1; - } - - JSRuntimeClient *client = JSRuntimeClient::getInstance(); - client->initialize(WS_SERVER_PORT); - if (!client->run()) - { - NativeJSLogger::log(ERROR, "Unable to connect to server\n"); - return -1; - } + if (argc > 1) + { + NativeJSLogger::log(INFO, "Send input commands at ws://localhost:%s\n", std::to_string(WS_SERVER_PORT).c_str()); + return -1; + } - while (client->getState() == "open" && std::getline(std::cin, command)) - { - client->sendCommand(command, response); - if (!response.empty()) + JSRuntimeClient *client = JSRuntimeClient::getInstance(); + client->initialize(WS_SERVER_PORT); + if (!client->run()) { - NativeJSLogger::log(INFO, "Response: %s\n", response.c_str()); + NativeJSLogger::log(ERROR, "Unable to connect to server\n"); + return -1; } - else + + while (client->getState() == "open" && std::getline(std::cin, command)) { - NativeJSLogger::log(WARN, "Missing response\n"); - break; + client->sendCommand(command, response); + if (!response.empty()) + { + NativeJSLogger::log(INFO, "Response: %s\n", response.c_str()); + } + else + { + NativeJSLogger::log(WARN, "Missing response\n"); + break; + } } - } - return 0; + return 0; + } catch (const std::exception& e) { + NativeJSLogger::log(ERROR, "Uncaught exception in main: %s\n", e.what()); + return -1; + } catch (...) { + NativeJSLogger::log(ERROR, "Unknown exception caught in main\n"); + return -1; + } } #endif diff --git a/src/JSRuntimeClientContainer.cpp b/src/JSRuntimeClientContainer.cpp index 8382be2..5b98681 100644 --- a/src/JSRuntimeClientContainer.cpp +++ b/src/JSRuntimeClientContainer.cpp @@ -6,26 +6,36 @@ #include "NativeJSLogger.h" int main() { - std::string containerId = "com.sky.as.apps_TestApp"; - const std::string basePath = "/opt/twocontext"; // constant base path - const std::vector apps = {"app1", "app2"}; - - std::string ipAddress = JSRuntimeContainer::getContainerIpAddress(containerId); - if (ipAddress.empty()) { - NativeJSLogger::log(ERROR, "Failed to retrieve IP address for container"); - return 1; - } + try { + std::string containerId = "com.sky.as.apps_TestApp"; + const std::string basePath = "/opt/twocontext"; // constant base path + const std::vector apps = {"app1", "app2"}; + + std::string ipAddress = JSRuntimeContainer::getContainerIpAddress(containerId); + if (ipAddress.empty()) { + NativeJSLogger::log(ERROR, "Failed to retrieve IP address for container\n"); + return 1; + } - for (const auto &app : apps) { - std::string url = basePath + std::string("/") + app + std::string("/index.html"); - if (access(url.c_str(), F_OK) == 0) { - std::string pathAppConfig = basePath + std::string("/") + app + std::string("/app.config"); - std::string options = JSRuntimeContainer::parseAppConfig(pathAppConfig); - std::string message = JSRuntimeContainer::buildLaunchMessage(url, options); - JSRuntimeContainer::connectAndSend(ipAddress, message); + for (const auto &app : apps) { + std::string url = basePath + std::string("/") + app + std::string("/index.html"); + if (access(url.c_str(), F_OK) == 0) { + std::string pathAppConfig = basePath + std::string("/") + app + std::string("/app.config"); + std::string options = JSRuntimeContainer::parseAppConfig(pathAppConfig); + std::string message = JSRuntimeContainer::buildLaunchMessage(url, options); + JSRuntimeContainer::connectAndSend(ipAddress, message); + } } - } - return 0; + return 0; + } + catch (const std::exception& e) { + NativeJSLogger::log(ERROR, "Exception in main: %s\n", e.what()); + return 1; + } + catch (...) { + NativeJSLogger::log(ERROR, "Unknown exception in main\n"); + return 1; + } } diff --git a/src/JSRuntimeServer.cpp b/src/JSRuntimeServer.cpp index 342f386..520e7ee 100644 --- a/src/JSRuntimeServer.cpp +++ b/src/JSRuntimeServer.cpp @@ -85,6 +85,7 @@ class JsonWrap if (!itm || !cJSON_IsNumber(itm)) { std::cerr << "Error: " << name << "is not a Uint32_t" << std::endl; + res=0; err = true; } else diff --git a/src/NativeJSRenderer.cpp b/src/NativeJSRenderer.cpp index bee81b9..10ddda7 100644 --- a/src/NativeJSRenderer.cpp +++ b/src/NativeJSRenderer.cpp @@ -225,10 +225,8 @@ void NativeJSRenderer::setEnvForConsoleMode(ModuleSettings& moduleSettings) uint32_t NativeJSRenderer::createApplicationIdentifier() { - static uint32_t id = 1; - uint32_t ret = id; - id++; - return ret; + static std::atomic id{1}; + return id++; } uint32_t NativeJSRenderer::createApplication(ModuleSettings& moduleSettings, std::string userAgent) @@ -292,6 +290,7 @@ bool NativeJSRenderer::terminateApplication(uint32_t id) return true; } +// REQUIRES: Caller must hold mUserMutex void NativeJSRenderer::createApplicationInternal(ApplicationRequest& appRequest) { double startTime = getTimeInMilliSec(); @@ -330,9 +329,9 @@ void NativeJSRenderer::createApplicationInternal(ApplicationRequest& appRequest) context->setCreateApplicationEndTime(endTime, id); mContextMap[id].context=context; - mUserMutex.unlock(); } +// REQUIRES: Caller must hold mUserMutex void NativeJSRenderer::runApplicationInternal(ApplicationRequest& appRequest) { uint32_t id = appRequest.mId; @@ -365,7 +364,7 @@ void NativeJSRenderer::runApplicationInternal(ApplicationRequest& appRequest) NativeJSLogger::log(INFO, "Adding the window location: %s to js file\n", window.str().c_str()); context->runScript(window.str().c_str(),true, url, nullptr, true); } - NativeJSLogger::log(INFO, "nativeJS application thunder execution url: %s, result: %d\n", url.c_str(), ret ? 1 : 0); + NativeJSLogger::log(INFO, "nativeJS application thunder execution url: %s\n", url.c_str()); ret = context->runScript(chunk.contentsBuffer, true, url, nullptr, true); NativeJSLogger::log(INFO, "nativeJS application execution result: %d\n", ret ? 1 : 0); double duration = context->getExecutionDuration(); @@ -398,6 +397,7 @@ void NativeJSRenderer::runApplicationInternal(ApplicationRequest& appRequest) } } +// REQUIRES: Caller must hold mUserMutex void NativeJSRenderer::runJavaScriptInternal(ApplicationRequest& appRequest) { uint32_t id = appRequest.mId; @@ -427,6 +427,7 @@ void NativeJSRenderer::runJavaScriptInternal(ApplicationRequest& appRequest) } } +// REQUIRES: Caller must hold mUserMutex void NativeJSRenderer::terminateApplicationInternal(ApplicationRequest& AppRequest) { uint32_t id = AppRequest.mId; @@ -445,7 +446,7 @@ void NativeJSRenderer::terminateApplicationInternal(ApplicationRequest& AppReque else { - NativeJSLogger::log(ERROR, "Unable to find application with id: %d and url: %s\n", id, mContextMap[id].url); + NativeJSLogger::log(ERROR, "Unable to find application with id: %d\n", id); return ; } @@ -468,11 +469,10 @@ void NativeJSRenderer::run() { while(mRunning) { - uint32_t id; - mUserMutex.lock(); if (mConsoleMode) { processDevConsoleRequests(); } + mUserMutex.lock(); for (int i=0; i localQueue; + + // Move items from shared queue to local queue while holding the lock mConsoleState->inputMutex.lock(); - if (mConsoleState->codeToExecute.empty()) { mConsoleState->inputMutex.unlock(); return; } + localQueue.swap(mConsoleState->codeToExecute); + mConsoleState->inputMutex.unlock(); std::lock_guard lockg(mConsoleState->isProcessing_cv_m); bool dataProcessed = false; - for (; !mConsoleState->codeToExecute.empty(); mConsoleState->codeToExecute.pop_front()) { - bool ret = mConsoleState->consoleContext->runScript(mConsoleState->codeToExecute.front().c_str(), false); + // Process items from local queue (no race condition) + for (const auto& code : localQueue) { + bool ret = mConsoleState->consoleContext->runScript(code.c_str(), false); dataProcessed = true; } @@ -550,8 +558,6 @@ void NativeJSRenderer::processDevConsoleRequests() mConsoleState->isProcessing = false; mConsoleState->isProcessing_cv.notify_one(); } - - mConsoleState->inputMutex.unlock(); } std::atomic_bool NativeJSRenderer::consoleLoop = true; @@ -620,18 +626,30 @@ bool NativeJSRenderer::downloadFile(std::string& url, MemoryStruct& chunk) curl = curl_easy_init(); if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&chunk); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - curl_easy_setopt(curl, CURLOPT_PROXY, ""); + // Helper lambda to check curl_easy_setopt results + auto setOptWithCheck = [&curl](CURLoption option, auto value, const char* optionName) -> bool { + CURLcode res = curl_easy_setopt(curl, option, value); + if (res != CURLE_OK) { + NativeJSLogger::log(ERROR, "Failed to set %s: %s\n", optionName, curl_easy_strerror(res)); + curl_easy_cleanup(curl); + curl = nullptr; + return false; + } + return true; + }; + + if (!setOptWithCheck(CURLOPT_URL, url.c_str(), "CURLOPT_URL")) return ret; + if (!setOptWithCheck(CURLOPT_FOLLOWLOCATION, 1L, "CURLOPT_FOLLOWLOCATION")) return ret; + if (!setOptWithCheck(CURLOPT_HEADERFUNCTION, HeaderCallback, "CURLOPT_HEADERFUNCTION")) return ret; + if (!setOptWithCheck(CURLOPT_HEADERDATA, (void *)&chunk, "CURLOPT_HEADERDATA")) return ret; + if (!setOptWithCheck(CURLOPT_WRITEFUNCTION, WriteMemoryCallback, "CURLOPT_WRITEFUNCTION")) return ret; + if (!setOptWithCheck(CURLOPT_WRITEDATA, (void *)&chunk, "CURLOPT_WRITEDATA")) return ret; + if (!setOptWithCheck(CURLOPT_TIMEOUT, 30L, "CURLOPT_TIMEOUT")) return ret; + if (!setOptWithCheck(CURLOPT_NOSIGNAL, 1L, "CURLOPT_NOSIGNAL")) return ret; + if (!setOptWithCheck(CURLOPT_SSL_VERIFYHOST, 2L, "CURLOPT_SSL_VERIFYHOST")) return ret; + if (!setOptWithCheck(CURLOPT_SSL_VERIFYPEER, 1L, "CURLOPT_SSL_VERIFYPEER")) return ret; + if (!setOptWithCheck(CURLOPT_USERAGENT, "libcurl-agent/1.0", "CURLOPT_USERAGENT")) return ret; + if (!setOptWithCheck(CURLOPT_PROXY, "", "CURLOPT_PROXY")) return ret; //curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); diff --git a/src/jsc/JavaScriptContext.cpp b/src/jsc/JavaScriptContext.cpp index a0af753..3dd3389 100644 --- a/src/jsc/JavaScriptContext.cpp +++ b/src/jsc/JavaScriptContext.cpp @@ -119,6 +119,13 @@ if (mModuleSettings.enablePlayer) gTopLevelContext = nullptr; } mPriv->releaseAllProtected(); + + if (mNetworkMetricsData) + { + delete mNetworkMetricsData; + mNetworkMetricsData = nullptr; + } + JSGlobalContextRelease(mContext); JSContextGroupRelease(mContextGroup); rtLogInfo("%s end", __FUNCTION__); @@ -394,7 +401,7 @@ if (mModuleSettings.enablePlayer) gAAMPJSBindings = new AAMPJSBindings(); loadAAMPJSBindingsLib(); } - if (gAAMPJSBindings->fnLoadJS) + if (gAAMPJSBindings && gAAMPJSBindings->fnLoadJS) { gAAMPJSBindings->fnLoadJS(mContext); } diff --git a/src/jsc/JavaScriptEngine.cpp b/src/jsc/JavaScriptEngine.cpp index bafd1d7..84190ee 100644 --- a/src/jsc/JavaScriptEngine.cpp +++ b/src/jsc/JavaScriptEngine.cpp @@ -135,7 +135,7 @@ bool JavaScriptEngine::initialize() if (garbageCollectInterval) { garbageCollectIntervalValue = atof(garbageCollectInterval); - NativeJSLogger::log(INFO, "garbage collection interval value: %d\n", garbageCollectIntervalValue); + NativeJSLogger::log(INFO, "garbage collection interval value: %f\n", garbageCollectIntervalValue); } mGarbageCollectionTag = installTimeout(garbageCollectIntervalValue, true, [engine] () mutable { diff --git a/src/jsc/JavaScriptUtils.cpp b/src/jsc/JavaScriptUtils.cpp index 5476746..9b923ff 100644 --- a/src/jsc/JavaScriptUtils.cpp +++ b/src/jsc/JavaScriptUtils.cpp @@ -113,9 +113,11 @@ rtString jsToRtString(JSStringRef str) void dispatchPending() { - std::unique_lock lock(gDispatchMutex); - std::list> pending = std::move(gPendingFun); - gDispatchMutex.unlock(); + std::list> pending; + { + std::lock_guard lock(gDispatchMutex); + pending = std::move(gPendingFun); + } for(auto& fun : pending) fun(); } @@ -188,7 +190,10 @@ void assertIsMainThread() { AddRef(); if (!downloadRequest->errorString().isEmpty()) { + // Lambda captures by value - pointer fields are properly initialized + // coverity[uninit_member : FALSE] dispatchOnMainLoop( + /* coverity[uninit_member : FALSE] */ [this, errorString = downloadRequest->errorString(), statusCode = downloadRequest->downloadStatusCode()] () { if (statusCode == 28) @@ -241,7 +246,10 @@ void assertIsMainThread() } rtObjectRef protectedRef = resp; + // Lambda captures by value - pointer fields are properly initialized + // coverity[uninit_member : FALSE] dispatchOnMainLoop( + /* coverity[uninit_member : FALSE] */ [this, resp = resp, ref = protectedRef] () { mEmit.send("response", ref); resp->onData(); @@ -317,21 +325,48 @@ rtError rtReadBinaryBinding(int numArgs, const rtValue* args, rtValue* result, v char *buffer = nullptr; FILE *ptr = nullptr; ptr = fopen("hello.wasm","rb"); // r for read, b for binary + + if (!ptr) + { + rtLogError("Failed to open file: hello.wasm"); + return RT_ERROR; + } const char *fd = "hello.wasm"; struct stat buf; - stat(fd, &buf); + if (stat(fd, &buf) != 0) + { + rtLogError("Failed to stat file: %s", fd); + fclose(ptr); + return RT_ERROR; + } + int size = buf.st_size; buffer = (char*)malloc(size); - fread(buffer,size,1,ptr); // read 10 bytes to our buffer + if (!buffer) + { + rtLogError("Failed to allocate memory for file buffer"); + fclose(ptr); + return RT_ERROR; + } + size_t bytesRead = fread(buffer, 1, size, ptr); fclose(ptr); + if (bytesRead != (size_t)size) + { + rtLogError("Failed to read file: expected %d bytes, read %zu bytes", size, bytesRead); + free(buffer); + return RT_ERROR; + } + if (result) { result->setString(buffer); } + + free(buffer); return RT_OK; } @@ -693,6 +728,7 @@ rtError rtJSRuntimeDownloadMetrics(int numArgs, const rtValue* args, rtValue* re rtValue keys; if (map->Get("allKeys", &keys) != RT_OK) { rtLogWarn("Could not retrieve url for network metrics data."); + delete netMetricsArray; return RT_FAIL; } rtObjectRef objRef = keys.toObject(); @@ -700,6 +736,7 @@ rtError rtJSRuntimeDownloadMetrics(int numArgs, const rtValue* args, rtValue* re if (!keysArray) { rtLogWarn("No url found in the network metrics data."); + delete netMetricsArray; return RT_FAIL; } @@ -715,6 +752,7 @@ rtError rtJSRuntimeDownloadMetrics(int numArgs, const rtValue* args, rtValue* re NetworkMetrics* metrics = (NetworkMetrics*)storedValue.toVoidPtr(); if (!metrics) { rtLogError("Failed to cast stored value to NetworkMetrics structure for url: %s.", key.cString()); + delete netMetricsArray; return RT_FAIL; } rtMapObject* metricsMap = new rtMapObject(); diff --git a/src/jsc/jsc_lib/jsc_lib.cpp b/src/jsc/jsc_lib/jsc_lib.cpp index b759135..b652a35 100644 --- a/src/jsc/jsc_lib/jsc_lib.cpp +++ b/src/jsc/jsc_lib/jsc_lib.cpp @@ -29,9 +29,9 @@ static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } static bool shouldInterruptScript(const JSGlobalObject*) { return true; } static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; } static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); } -static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, Exception* exception) +static void reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObject, Exception* exception) { - NativeJSLogger::log(ERROR, "Uncaught Exception at run loop: %s\n", exception->value()); + NativeJSLogger::log(ERROR, "Uncaught Exception at run loop: %s\n", exception->value().toWTFString(globalObject).utf8().data()); } static JSObject* currentScriptExecutionOwner(JSGlobalObject* global) { return global; } static ScriptExecutionStatus scriptExecutionStatus(JSGlobalObject*, JSObject*) { return ScriptExecutionStatus::Running; } @@ -150,18 +150,30 @@ bool downloadFile(std::string& url, MemoryStruct& chunk) curl = curl_easy_init(); if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, CallbackHeader); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&chunk); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CallbackOnMemoryWrite); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - curl_easy_setopt(curl, CURLOPT_PROXY, ""); + // Helper lambda to check curl_easy_setopt results + auto setOptWithCheck = [&curl](CURLoption option, auto value, const char* optionName) -> bool { + CURLcode res = curl_easy_setopt(curl, option, value); + if (res != CURLE_OK) { + NativeJSLogger::log(ERROR, "Failed to set %s: %s\n", optionName, curl_easy_strerror(res)); + curl_easy_cleanup(curl); + curl = nullptr; + return false; + } + return true; + }; + + if (!setOptWithCheck(CURLOPT_URL, url.c_str(), "CURLOPT_URL")) return ret; + if (!setOptWithCheck(CURLOPT_FOLLOWLOCATION, 1L, "CURLOPT_FOLLOWLOCATION")) return ret; + if (!setOptWithCheck(CURLOPT_HEADERFUNCTION, CallbackHeader, "CURLOPT_HEADERFUNCTION")) return ret; + if (!setOptWithCheck(CURLOPT_HEADERDATA, (void *)&chunk, "CURLOPT_HEADERDATA")) return ret; + if (!setOptWithCheck(CURLOPT_WRITEFUNCTION, CallbackOnMemoryWrite, "CURLOPT_WRITEFUNCTION")) return ret; + if (!setOptWithCheck(CURLOPT_WRITEDATA, (void *)&chunk, "CURLOPT_WRITEDATA")) return ret; + if (!setOptWithCheck(CURLOPT_TIMEOUT, 30L, "CURLOPT_TIMEOUT")) return ret; + if (!setOptWithCheck(CURLOPT_NOSIGNAL, 1L, "CURLOPT_NOSIGNAL")) return ret; + if (!setOptWithCheck(CURLOPT_SSL_VERIFYHOST, 2L, "CURLOPT_SSL_VERIFYHOST")) return ret; + if (!setOptWithCheck(CURLOPT_SSL_VERIFYPEER, 1L, "CURLOPT_SSL_VERIFYPEER")) return ret; + if (!setOptWithCheck(CURLOPT_USERAGENT, "libcurl-agent/1.0", "CURLOPT_USERAGENT")) return ret; + if (!setOptWithCheck(CURLOPT_PROXY, "", "CURLOPT_PROXY")) return ret; //curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); @@ -388,7 +400,7 @@ static URL currentWorkingDirectory() return { }; // Add a trailing slash if needed so the URL resolves to a directory and not a file. - if (directoryString[directoryString.length() - 1] != pathSeparator()) + if (!directoryString.endsWith(pathSeparator())) directoryString = makeString(directoryString, pathSeparator()); return URL::fileURLWithFileSystemPath(directoryString); diff --git a/src/jsruntime.cpp b/src/jsruntime.cpp index fdbf989..2454a9a 100644 --- a/src/jsruntime.cpp +++ b/src/jsruntime.cpp @@ -37,6 +37,7 @@ using namespace JsRuntime; #ifndef UNIT_TEST_BUILD int main(int argc, char* argv[]) { + try { if (argc < 2) { NativeJSLogger::log(WARN, "Pass the URL to run\n"); @@ -57,7 +58,9 @@ int main(int argc, char* argv[]) { appendindex = i-1; i++; - waylanddisplay = argv[i]; + if (i < argc) { + waylanddisplay = argv[i]; + } } else if (strcmp(argv[i], "--enableHttp") == 0) { @@ -107,16 +110,16 @@ int main(int argc, char* argv[]) } i++; } - + + // CID:430751 - Intentional: waylanddisplay from command line argument + // This is a display socket name passed to Wayland compositor, used only for + // local display connection. The value is passed to system compositor APIs + // which handle validation. No injection risk as it's used as display identifier only. + /* coverity[tainted_data] */ std::shared_ptr renderer = std::make_shared(waylanddisplay); if (consoleMode) { renderer->setEnvForConsoleMode(moduleSettings); } - if (!renderer) - { - NativeJSLogger::log(ERROR, "Unable to run application\n"); - return -1; - } #if defined(ENABLE_JSRUNTIME_SERVER) if (runServer == true) @@ -172,6 +175,13 @@ int main(int argc, char* argv[]) } return 0; + } catch (const std::exception& e) { + NativeJSLogger::log(ERROR, "Uncaught exception in main: %s\n", e.what()); + return -1; + } catch (...) { + NativeJSLogger::log(ERROR, "Unknown exception caught in main\n"); + return -1; + } } #endif