mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-06 19:48:35 +01:00
Fix/sonar reliability security (#205)
* fix(sonar): addressing reliability/security issues * fix(sonar): addressing reliability/security issues * fix(sonar): addressing reliability/security issues * fix(sonar): addressing last reliability/security issues * fix(sonar): addressing last reliability/security issues * fix(sonar): addressing last reliability/security issues * refactor(sonar): imgui update * refactor(sonar): hasChar revert
This commit is contained in:
@@ -569,7 +569,7 @@ int eu07_application::run()
|
|||||||
if (m_network && m_network->client)
|
if (m_network && m_network->client)
|
||||||
{
|
{
|
||||||
// verify sync
|
// verify sync
|
||||||
if (sync != slave_sync) // NOSONAR
|
if (sync != slave_sync) // NOSONAR slave_sync is initialised, the PR analysis keeps a stale report of the old declaration
|
||||||
{
|
{
|
||||||
WriteLog("net: desync! calculated: " + std::to_string(sync) + ", received: " + std::to_string(slave_sync), logtype::net);
|
WriteLog("net: desync! calculated: " + std::to_string(sync) + ", received: " + std::to_string(slave_sync), logtype::net);
|
||||||
|
|
||||||
@@ -1464,7 +1464,8 @@ int eu07_application::init_data()
|
|||||||
|
|
||||||
int eu07_application::init_modes()
|
int eu07_application::init_modes()
|
||||||
{
|
{
|
||||||
Global.local_random_engine.seed(static_cast<std::mt19937::result_type>(true_random_seed()));
|
// local cosmetics only (sound pitch, editor placement), never security related
|
||||||
|
Global.local_random_engine.seed(static_cast<std::mt19937::result_type>(true_random_seed())); // NOSONAR
|
||||||
|
|
||||||
if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty())
|
if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ bool ImGui_NVRHI::createFontTexture(nvrhi::ICommandList* commandList)
|
|||||||
commandList->setPermanentTextureState(fontTexture, nvrhi::ResourceStates::ShaderResource);
|
commandList->setPermanentTextureState(fontTexture, nvrhi::ResourceStates::ShaderResource);
|
||||||
commandList->commitBarriers();
|
commandList->commitBarriers();
|
||||||
|
|
||||||
io.Fonts->TexID = fontTexture;
|
// since imgui 1.91 ImTextureID is an integer, not a pointer
|
||||||
|
io.Fonts->TexID = static_cast<ImTextureID>(reinterpret_cast<uintptr_t>(fontTexture.Get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -371,7 +372,7 @@ bool ImGui_NVRHI::render(nvrhi::IFramebuffer* framebuffer)
|
|||||||
{
|
{
|
||||||
pCmd->UserCallback(cmdList, pCmd);
|
pCmd->UserCallback(cmdList, pCmd);
|
||||||
} else {
|
} else {
|
||||||
drawState.bindings = { getBindingSet(pCmd->TextureId) };
|
drawState.bindings = { getBindingSet(reinterpret_cast<void*>(static_cast<uintptr_t>(pCmd->GetTexID()))) };
|
||||||
assert(drawState.bindings[0]);
|
assert(drawState.bindings[0]);
|
||||||
|
|
||||||
drawState.viewport.scissorRects[0] = nvrhi::Rect(int(pCmd->ClipRect.x),
|
drawState.viewport.scissorRects[0] = nvrhi::Rect(int(pCmd->ClipRect.x),
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
|
|||||||
|
|
||||||
// Generate hemisphere kernel (z > 0 = toward surface normal)
|
// Generate hemisphere kernel (z > 0 = toward surface normal)
|
||||||
std::uniform_real_distribution<float> rnd(0.0f, 1.0f);
|
std::uniform_real_distribution<float> rnd(0.0f, 1.0f);
|
||||||
std::default_random_engine gen(42); // fixed seed for consistency
|
std::default_random_engine gen(42); // NOSONAR fixed seed on purpose, SSAO kernel has to be identical every run
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
glm::vec3 s(rnd(gen)*2.0f-1.0f, rnd(gen)*2.0f-1.0f, rnd(gen));
|
glm::vec3 s(rnd(gen)*2.0f-1.0f, rnd(gen)*2.0f-1.0f, rnd(gen));
|
||||||
s = glm::normalize(s) * rnd(gen);
|
s = glm::normalize(s) * rnd(gen);
|
||||||
@@ -1532,7 +1532,7 @@ glm::mat4 opengl33_renderer::perspective_projection_raw(float fovy, float aspect
|
|||||||
{
|
{
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
||||||
{
|
{
|
||||||
const float f = 1.0f / tan(fovy / 2.0f);
|
const float f = 1.0f / std::tan(fovy / 2.0f);
|
||||||
|
|
||||||
// when clip_control available, use projection matrix with 1..0 Z range and infinite zfar
|
// when clip_control available, use projection matrix with 1..0 Z range and infinite zfar
|
||||||
return glm::mat4( //
|
return glm::mat4( //
|
||||||
|
|||||||
@@ -614,7 +614,8 @@ std::string deserialize_random_set(cParser &Input, char const *Break)
|
|||||||
}
|
}
|
||||||
if (false == tokens.empty())
|
if (false == tokens.empty())
|
||||||
{
|
{
|
||||||
std::ranges::shuffle(tokens, Global.random_engine);
|
// scenery random set: must replay from the shared run seed, not a security concern
|
||||||
|
std::shuffle(std::begin(tokens), std::end(tokens), Global.random_engine); // NOSONAR
|
||||||
return tokens.front();
|
return tokens.front();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -317,8 +317,7 @@ TSegment::find_nearest_point( glm::dvec3 const &Point ) const {
|
|||||||
distance = segmentdistance;
|
distance = segmentdistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
return nearest; // NOSONAR initialised above, the PR analysis keeps a stale report of the old declaration
|
||||||
return nearest;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,14 +562,14 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
|||||||
|
|
||||||
void TSegment::render_lines(std::vector<gfx::basic_vertex> &out, float quality) const
|
void TSegment::render_lines(std::vector<gfx::basic_vertex> &out, float quality) const
|
||||||
{
|
{
|
||||||
float step = 1.0f / static_cast<float>(iSegCount) / quality;
|
float step = 1.0f / iSegCount / quality;
|
||||||
|
auto const stepcount = static_cast<int>(static_cast<float>(iSegCount) * quality);
|
||||||
|
|
||||||
glm::vec3 previous = FastGetPoint(0.0);
|
glm::vec3 previous = FastGetPoint(0.0);
|
||||||
|
|
||||||
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
|
for (int i = 1; i <= stepcount; ++i) {
|
||||||
float const x = static_cast<float>(i) * step;
|
float const x = std::min(1.0f, static_cast<float>(i) * step);
|
||||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
|
||||||
|
|
||||||
previous = glm::vec3(FastGetPoint(x));
|
previous = glm::vec3(FastGetPoint(x));
|
||||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
||||||
@@ -584,14 +583,14 @@ void TSegment::render_lines(std::vector<gfx::basic_vertex> &out, float quality)
|
|||||||
|
|
||||||
glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) const
|
glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) const
|
||||||
{
|
{
|
||||||
float step = 1.0f / static_cast<float>(iSegCount) / quality;
|
float step = 1.0f / iSegCount / quality;
|
||||||
|
auto const stepcount = static_cast<int>(static_cast<float>(iSegCount) * quality);
|
||||||
|
|
||||||
glm::vec3 nearest;
|
glm::vec3 nearest;
|
||||||
float min = std::numeric_limits<float>::max();
|
float min = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
|
for (int i = 1; i <= stepcount; ++i) {
|
||||||
float const x = static_cast<float>(i) * step;
|
float const x = std::min(1.0f, static_cast<float>(i) * step);
|
||||||
glm::vec3 p1 = FastGetPoint(x);
|
glm::vec3 p1 = FastGetPoint(x);
|
||||||
|
|
||||||
if (glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step)); p1 != p2) {
|
if (glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step)); p1 != p2) {
|
||||||
|
|||||||
108
world/Track.cpp
108
world/Track.cpp
@@ -3720,6 +3720,58 @@ std::vector<TSegment *> sleeper_segments_for( TTrack const &Track )
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Local-space transform (relative to Origin) of the sleeper at distance S along the Segment,
|
||||||
|
// or none at a degenerate spot (e.g. zero-length sub-segment) where no tangent can be taken.
|
||||||
|
// Eps is the half-span of the central difference used to extract the tangent.
|
||||||
|
std::optional<glm::mat4> sleeper_transform( TSegment const &Segment, double const S, double const Eps, glm::dvec3 const &Origin, glm::vec3 const &Offset )
|
||||||
|
{
|
||||||
|
glm::dvec3 pos;
|
||||||
|
glm::vec3 angles;
|
||||||
|
Segment.RaPositionGet( S, pos, angles );
|
||||||
|
|
||||||
|
// tangent direction via central difference (clamped to the segment endpoints)
|
||||||
|
glm::dvec3 p_back;
|
||||||
|
glm::dvec3 p_fwd;
|
||||||
|
glm::vec3 dummy;
|
||||||
|
Segment.RaPositionGet( std::max( 0.0, S - Eps ), p_back, dummy );
|
||||||
|
Segment.RaPositionGet( std::min( Segment.GetLength(), S + Eps ), p_fwd, dummy );
|
||||||
|
auto tangent = glm::vec3( p_fwd - p_back );
|
||||||
|
if( glm::length2( tangent ) < 1e-8f ) {
|
||||||
|
// skip this position rather than emit a junk transform with NaN normals.
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
tangent = glm::normalize( tangent );
|
||||||
|
|
||||||
|
// build an orthonormal basis around the tangent. world up is the reference; if the
|
||||||
|
// track is almost vertical we fall back to world X so cross() doesn't collapse.
|
||||||
|
glm::vec3 up_ref { 0.f, 1.f, 0.f };
|
||||||
|
if( std::abs( glm::dot( tangent, up_ref ) ) > 0.999f ) { up_ref = glm::vec3( 1.f, 0.f, 0.f ); }
|
||||||
|
glm::vec3 side = glm::normalize( glm::cross( up_ref, tangent ) );
|
||||||
|
glm::vec3 up = glm::cross( tangent, side );
|
||||||
|
|
||||||
|
// apply track roll (banking) around the tangent / forward axis.
|
||||||
|
if( float const roll = angles.x; roll != 0.f ) {
|
||||||
|
auto const roll_mat = glm::rotate( glm::mat4( 1.f ), roll, tangent );
|
||||||
|
side = glm::vec3( roll_mat * glm::vec4( side, 0.f ) );
|
||||||
|
up = glm::vec3( roll_mat * glm::vec4( up, 0.f ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// assemble local transform: columns are (right, up, forward, translation).
|
||||||
|
// a sleeper modelled with X = sideways, Y = up, Z = along-track now ends up
|
||||||
|
// correctly oriented along the path tangent regardless of curve direction.
|
||||||
|
auto const localpos = glm::vec3( pos - Origin );
|
||||||
|
glm::mat4 m { 1.f };
|
||||||
|
m[ 0 ] = glm::vec4( side, 0.f );
|
||||||
|
m[ 1 ] = glm::vec4( up, 0.f );
|
||||||
|
m[ 2 ] = glm::vec4( tangent, 0.f );
|
||||||
|
m[ 3 ] = glm::vec4( localpos, 1.f );
|
||||||
|
|
||||||
|
if( Offset != glm::vec3( 0.f ) ) {
|
||||||
|
m = glm::translate( m, Offset );
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// Resolves the sleeper model + (optional) replacable skin via the global model/material
|
// Resolves the sleeper model + (optional) replacable skin via the global model/material
|
||||||
@@ -3764,13 +3816,12 @@ void TTrack::build_sleeper_transforms()
|
|||||||
// at the segment endpoints. Sampling positions directly is robust for both straight
|
// at the segment endpoints. Sampling positions directly is robust for both straight
|
||||||
// segments and bezier curves, and it costs us two extra evaluations per sleeper.
|
// segments and bezier curves, and it costs us two extra evaluations per sleeper.
|
||||||
double const eps = std::min( 0.1, spacing * 0.25 );
|
double const eps = std::min( 0.1, spacing * 0.25 );
|
||||||
glm::vec3 const world_up { 0.f, 1.f, 0.f };
|
|
||||||
|
|
||||||
// user offset is (left/right, forward/back, up/down) in the local frame established by
|
// user offset is (left/right, forward/back, up/down) in the local frame established by
|
||||||
// the basis below (x=right, y=up, z=forward). swap y<->z to match the documented axes.
|
// the basis below (x=right, y=up, z=forward). swap y<->z to match the documented axes.
|
||||||
glm::vec3 const local_offset { m_sleeper_offset.x, m_sleeper_offset.z, m_sleeper_offset.y };
|
glm::vec3 const local_offset { m_sleeper_offset.x, m_sleeper_offset.z, m_sleeper_offset.y };
|
||||||
|
|
||||||
for( auto *segment : segments ) {
|
for( auto const *segment : segments ) {
|
||||||
auto const length = segment->GetLength();
|
auto const length = segment->GetLength();
|
||||||
if( length <= 0.0 ) { continue; }
|
if( length <= 0.0 ) { continue; }
|
||||||
// start half a frequency in so the first sleeper doesn't sit on the joint.
|
// start half a frequency in so the first sleeper doesn't sit on the joint.
|
||||||
@@ -3778,55 +3829,12 @@ void TTrack::build_sleeper_transforms()
|
|||||||
auto const expected = static_cast<std::size_t>( std::max( 0.0, ( length - start ) / spacing ) ) + 1u;
|
auto const expected = static_cast<std::size_t>( std::max( 0.0, ( length - start ) / spacing ) ) + 1u;
|
||||||
m_sleeper_local_transforms.reserve( m_sleeper_local_transforms.size() + expected );
|
m_sleeper_local_transforms.reserve( m_sleeper_local_transforms.size() + expected );
|
||||||
|
|
||||||
for( double s = start; s < length; s += spacing ) {
|
for( std::size_t sleeperidx = 0;; ++sleeperidx ) {
|
||||||
glm::dvec3 pos;
|
auto const s = start + static_cast<double>( sleeperidx ) * spacing;
|
||||||
glm::vec3 angles;
|
if( s >= length ) { break; }
|
||||||
segment->RaPositionGet( s, pos, angles );
|
if( auto const transform = sleeper_transform( *segment, s, eps, m_origin, local_offset ) ) {
|
||||||
|
m_sleeper_local_transforms.emplace_back( *transform );
|
||||||
// tangent direction via central difference (clamped to the segment endpoints)
|
|
||||||
auto const s_back = std::max( 0.0, s - eps );
|
|
||||||
auto const s_fwd = std::min( length, s + eps );
|
|
||||||
glm::dvec3 p_back, p_fwd;
|
|
||||||
glm::vec3 dummy;
|
|
||||||
segment->RaPositionGet( s_back, p_back, dummy );
|
|
||||||
segment->RaPositionGet( s_fwd, p_fwd, dummy );
|
|
||||||
auto tangent = glm::vec3( p_fwd - p_back );
|
|
||||||
if( glm::length2( tangent ) < 1e-8f ) {
|
|
||||||
// degenerate sample (e.g. zero-length sub-segment); skip this position rather
|
|
||||||
// than emit a junk transform with NaN normals.
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
tangent = glm::normalize( tangent );
|
|
||||||
|
|
||||||
// build an orthonormal basis around the tangent. world up is the reference; if the
|
|
||||||
// track is almost vertical we fall back to world X so cross() doesn't collapse.
|
|
||||||
glm::vec3 up_ref = world_up;
|
|
||||||
if( std::abs( glm::dot( tangent, up_ref ) ) > 0.999f ) { up_ref = glm::vec3( 1.f, 0.f, 0.f ); }
|
|
||||||
glm::vec3 right = glm::normalize( glm::cross( up_ref, tangent ) );
|
|
||||||
glm::vec3 up = glm::cross( tangent, right );
|
|
||||||
|
|
||||||
// apply track roll (banking) around the tangent / forward axis.
|
|
||||||
float const roll = angles.x;
|
|
||||||
if( roll != 0.f ) {
|
|
||||||
auto const roll_mat = glm::rotate( glm::mat4( 1.f ), roll, tangent );
|
|
||||||
right = glm::vec3( roll_mat * glm::vec4( right, 0.f ) );
|
|
||||||
up = glm::vec3( roll_mat * glm::vec4( up, 0.f ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// assemble local transform: columns are (right, up, forward, translation).
|
|
||||||
// a sleeper modelled with X = sideways, Y = up, Z = along-track now ends up
|
|
||||||
// correctly oriented along the path tangent regardless of curve direction.
|
|
||||||
auto const localpos = glm::vec3( pos - m_origin );
|
|
||||||
glm::mat4 m { 1.f };
|
|
||||||
m[ 0 ] = glm::vec4( right, 0.f );
|
|
||||||
m[ 1 ] = glm::vec4( up, 0.f );
|
|
||||||
m[ 2 ] = glm::vec4( tangent, 0.f );
|
|
||||||
m[ 3 ] = glm::vec4( localpos, 1.f );
|
|
||||||
|
|
||||||
if( local_offset != glm::vec3( 0.f ) ) {
|
|
||||||
m = glm::translate( m, local_offset );
|
|
||||||
}
|
|
||||||
m_sleeper_local_transforms.emplace_back( m );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user