From 4137f5504ae71ee0bdd4415ac9dfba593e64d335 Mon Sep 17 00:00:00 2001 From: jerrrrycho Date: Mon, 28 Sep 2026 21:07:53 +0200 Subject: [PATCH] fix: sonar sast fixes - sonar.yml, nosonar, linux chmod modification --- .github/workflows/sonar.yml | 22 +++++++++++++++++++--- application/application.cpp | 2 +- sonar-project.properties | 4 +++- utilities/Globals.h | 10 ++++++++-- utilities/uart.cpp | 4 ++-- vehicle/Driver.cpp | 2 +- vehicle/DynObj.cpp | 3 ++- 7 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 8140317e..66213c23 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -70,7 +70,9 @@ jobs: pull-requests: read # verify PR head sha via the API env: BUILD_WRAPPER_OUT_DIR: bw-output - SONAR_EXCLUSIONS: betterRenderer/**,ref/**,imgui/**,stb/**,build/**,bw-output/** + # .trusted/ holds the checkout of master used to restore the scanner config; + # it is not part of the analysed change. + SONAR_EXCLUSIONS: betterRenderer/**,ref/**,imgui/**,stb/**,build/**,bw-output/**,.trusted/** SONAR_SCANNER_JAVA_OPTS: -Xmx5g steps: - name: Post pending status @@ -102,12 +104,26 @@ jobs: - name: Unpack analysis input run: | set -euo pipefail + # The archive holds the whole PR workspace and is unpacked over this one, + # .trusted/ included. Move the trusted config out of reach first, or a PR + # carrying its own .trusted/sonar-project.properties would have it planted + # here and restored below as if it came from master. + if [ -f "$GITHUB_WORKSPACE/.trusted/sonar-project.properties" ]; then + cp "$GITHUB_WORKSPACE/.trusted/sonar-project.properties" /tmp/trusted-sonar-project.properties + fi + # Nothing may be written outside the workspace: reject absolute members and + # any member reaching through a parent directory before unpacking anything. + tar -tzf /tmp/sonar-input/workspace.tar.gz > /tmp/archive-members.txt + if grep -qE '^/|(^|/)[.][.](/|$)' /tmp/archive-members.txt; then + echo "::error::archive contains paths outside the workspace" + exit 1 + fi tar -xzf /tmp/sonar-input/workspace.tar.gz -C "$GITHUB_WORKSPACE" # Strip PR-controlled scanner configuration, restore the trusted one. rm -f "$GITHUB_WORKSPACE/sonar-project.properties" \ "$GITHUB_WORKSPACE/.sonarcloud.properties" - if [ -f "$GITHUB_WORKSPACE/.trusted/sonar-project.properties" ]; then - cp "$GITHUB_WORKSPACE/.trusted/sonar-project.properties" "$GITHUB_WORKSPACE/" + if [ -f /tmp/trusted-sonar-project.properties ]; then + cp /tmp/trusted-sonar-project.properties "$GITHUB_WORKSPACE/sonar-project.properties" fi - name: Resolve and verify PR metadata diff --git a/application/application.cpp b/application/application.cpp index a6b88ae8..26af01fa 100644 --- a/application/application.cpp +++ b/application/application.cpp @@ -1105,7 +1105,7 @@ void eu07_application::init_files() #elif __unix__ unlink("log.txt"); unlink("errors.txt"); - mkdir("logs", 0755); + mkdir("logs", 0750); #endif } namespace fs = std::filesystem; diff --git a/sonar-project.properties b/sonar-project.properties index 2e3fc88b..a1e5b66c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -6,7 +6,9 @@ sonar.sources=. sonar.sourceEncoding=UTF-8 # Exclusions -sonar.exclusions=betterRenderer/**,ref/**,imgui/**,stb/**,build/**,bw-output/** +# .trusted/ is the copy of master the analysis workflow checks out to restore its +# own configuration; analysing it would duplicate every file of the base branch. +sonar.exclusions=betterRenderer/**,ref/**,imgui/**,stb/**,build/**,bw-output/**,.trusted/** # Excluding all files from coverage making the gate skip that # instead of failing it. diff --git a/utilities/Globals.h b/utilities/Globals.h index c4bd26f6..d0f70701 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -38,8 +38,14 @@ struct global_settings { bool shiftState{ false }; //m7todo: brzydko bool ctrlState{ false }; bool altState{ false }; - std::mt19937 random_engine; - std::mt19937 local_random_engine; + // Simulation randomness, never used for anything security related: no keys, tokens or + // credentials come out of these. Reproducibility is a requirement here, which is why both + // are plain mt19937 -- the run's seed can be written down and passed on, and it travels in + // server_hello so that every client in a session replays the same sequence. A generator + // that cannot be seeded to a known state would break both of those. + std::mt19937 random_engine; // NOSONAR shared run seed, kept in sync across the network + std::mt19937 local_random_engine; // NOSONAR re-seeded from a true random source in init_modes, + // drives purely local cosmetics (sound pitch, editor placement) bool ready_to_load{ false }; std::time_t starting_timestamp = 0; // starting time, in local timezone uint32_t random_seed = 0; diff --git a/utilities/uart.cpp b/utilities/uart.cpp index cac7a198..ab5060fa 100644 --- a/utilities/uart.cpp +++ b/utilities/uart.cpp @@ -399,7 +399,7 @@ void uart_input::poll() char buf[buffer.size() * 3 + 1]; size_t pos = 0; for (uint8_t b : buffer) - pos += sprintf(&buf[pos], "%02X ", b); + pos += snprintf(&buf[pos], sizeof(buf) - pos, "%02X ", b); WriteLog("uart: rx: " + std::string(buf)); } @@ -635,7 +635,7 @@ void uart_input::poll() buf[ buffer.size() * 3 ] = 0; size_t pos = 0; for (uint8_t b : buffer) - pos += sprintf(&buf[pos], "%02X ", b); + pos += snprintf(&buf[pos], sizeof(buf) - pos, "%02X ", b); WriteLog("uart: tx: " + std::string(buf)); } diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index 9a6de859..9771f7db 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -1901,7 +1901,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, #ifdef _WIN32 CreateDirectory( "physicslog", nullptr); #elif __unix__ - mkdir( "physicslog", 0744 ); + mkdir( "physicslog", 0740 ); #endif LogFile.open( std::string( "physicslog/" + VehicleName + ".dat" ), std::ios::in | std::ios::out | std::ios::trunc ); diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index e84af613..57cc8660 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -3024,7 +3024,8 @@ TDynamicObject::update_load_offset() { void TDynamicObject::shuffle_load_order() { - std::shuffle( std::begin( SectionLoadOrder ), std::end( SectionLoadOrder ), Global.random_engine ); + // order of visible load chunks, nothing security related -- see the engines in Globals.h + std::shuffle( std::begin( SectionLoadOrder ), std::end( SectionLoadOrder ), Global.random_engine ); // NOSONAR // shift chunks assigned to corridors to the end of the list, so they show up last std::stable_partition( std::begin( SectionLoadOrder ), std::end( SectionLoadOrder ),