From 46993b1ad39bc56c2c4038b6bcfceb1f6e44d7b6 Mon Sep 17 00:00:00 2001 From: jerrrrycho Date: Thu, 1 Oct 2026 19:33:53 +0200 Subject: [PATCH] fix: bound MotorParam and MPTRelay indices --- McZapkie/MOVER.h | 7 +++- McZapkie/Mover.cpp | 83 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index a6658494..e7bd1d23 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1086,7 +1086,7 @@ struct TMPTRelay double Iup = 0.0; double Idown = 0.0; }; -typedef TMPTRelay TMPTRelayTable[8]; +typedef TMPTRelay TMPTRelayTable[MotorParametersArraySize + 1]; // indexed like MotorParam struct TMotorParameters { @@ -1729,6 +1729,11 @@ class TMoverParameters TMotorParameters MotorParam[MotorParametersArraySize + 1]; /*rozne parametry silnika przy bocznikowaniach*/ /*dla lokomotywy spalinowej z przekladnia mechaniczna: przelozenia biegow*/ + // bounds-safe read access to MotorParam + TMotorParameters const &motor_param(int const Position) const + { + return MotorParam[std::clamp(Position, 0, MotorParametersArraySize)]; + } TTransmision Transmision; // record {liczba zebow przekladni} // NToothM, NToothW : byte; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 68b88918..01b5b2a0 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -355,7 +355,7 @@ double TMoverParameters::Current(double n, double U) if (DynamicBrakeFlag && !FuseFlag && DynamicBrakeType == dbrake_automatic && Power110vIsAvailable && Mains) // hamowanie EP09 //TUHEX { // TODO: zrobic bardziej uniwersalne nie tylko dla EP09 - MotorCurrent = -std::max(MotorParam[0].fi * (Vadd / (Vadd + MotorParam[0].Isat) - MotorParam[0].fi0), 0.) * n * 2.0 / DynamicBrakeRes; + MotorCurrent = -std::max(motor_param(0).fi * (Vadd / (Vadd + motor_param(0).Isat) - motor_param(0).fi0), 0.) * n * 2.0 / DynamicBrakeRes; } else if (RList[MainCtrlActualPos].Bn == 0 || false == StLinFlag) { @@ -390,7 +390,7 @@ double TMoverParameters::Current(double n, double U) if (DynamicBrakeType == dbrake_switch && TrainType == dt_ET42) { // z Megapacka Rz = WindingRes + R; - MotorCurrent = -MotorParam[SP].fi * n / Rz; //{hamowanie silnikiem na oporach rozruchowych} + MotorCurrent = -motor_param(SP).fi * n / Rz; //{hamowanie silnikiem na oporach rozruchowych} } } else @@ -398,13 +398,13 @@ double TMoverParameters::Current(double n, double U) } else { - U1 = U + Mn * n * MotorParam[SP].fi0 * MotorParam[SP].fi; + U1 = U + Mn * n * motor_param(SP).fi0 * motor_param(SP).fi; // writepaslog("U1 ", FloatToStr(U1)); // writepaslog("Isat ", FloatToStr(MotorParam[SP].Isat)); // writepaslog("fi ", FloatToStr(MotorParam[SP].fi)); - Isf = Sign(U1) * MotorParam[SP].Isat; + Isf = Sign(U1) * motor_param(SP).Isat; // writepaslog("Isf ", FloatToStr(Isf)); - Delta = square(Isf * Rz + Mn * MotorParam[SP].fi * n - U1) + 4.0 * U1 * Isf * Rz; // 105 * 1.67 + Mn * 140.9 * 20.532 - U1 + Delta = square(Isf * Rz + Mn * motor_param(SP).fi * n - U1) + 4.0 * U1 * Isf * Rz; // 105 * 1.67 + Mn * 140.9 * 20.532 - U1 // DeltaQ = Isf * Rz + Mn * MotorParam[SP].fi * n - U1 + 4 * U1 * Isf * Rz; // writepaslog("Delta ", FloatToStr(Delta)); // writepaslog("DeltaQ ", FloatToStr(DeltaQ)); @@ -412,9 +412,9 @@ double TMoverParameters::Current(double n, double U) if (Mains) { if (U > 0) - MotorCurrent = (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n + std::sqrt(Delta)) / (2.0 * Rz); + MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n + std::sqrt(Delta)) / (2.0 * Rz); else - MotorCurrent = (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n - std::sqrt(Delta)) / (2.0 * Rz); + MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n - std::sqrt(Delta)) / (2.0 * Rz); } else MotorCurrent = 0; @@ -5537,9 +5537,9 @@ double TMoverParameters::TractionForce(double dt) case TEngineType::DieselEngine: { if (ShuntMode) // dodatkowa przekładnia np. dla 2Ls150 - dtrans = AnPos * Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat; + dtrans = AnPos * Transmision.Ratio * motor_param(ScndCtrlActualPos).mIsat; else - dtrans = Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat; + dtrans = Transmision.Ratio * motor_param(ScndCtrlActualPos).mIsat; dmoment = dizel_Momentum(dizel_fill, dtrans * nrot * DirActive, dt); // oblicza tez enrot break; @@ -5984,10 +5984,10 @@ double TMoverParameters::TractionForce(double dt) Mm = Mw / Transmision.Ratio; // moment silnika trakcyjnego // with MotorParam[ScndCtrlPos] do - if (abs(Mm) > MotorParam[ScndCtrlPos].fi) - Im = NPoweredAxles * abs(abs(Mm) / MotorParam[ScndCtrlPos].mfi + MotorParam[ScndCtrlPos].mIsat); + if (abs(Mm) > motor_param(ScndCtrlPos).fi) + Im = NPoweredAxles * abs(abs(Mm) / motor_param(ScndCtrlPos).mfi + motor_param(ScndCtrlPos).mIsat); else - Im = NPoweredAxles * sqrt(abs(Mm * MotorParam[ScndCtrlPos].Isat)); + Im = NPoweredAxles * sqrt(abs(Mm * motor_param(ScndCtrlPos).Isat)); if (ShuntMode) { @@ -6765,7 +6765,7 @@ double TMoverParameters::Momentum(double I) SP = RList[MainCtrlActualPos].ScndAct; // Momentum:=mfi*I*(1-1.0/(Abs(I)/mIsat+1)); - return MotorParam[SP].mfi * I * (abs(I) / (abs(I) + MotorParam[SP].mIsat) - MotorParam[SP].mfi0); + return motor_param(SP).mfi * I * (abs(I) / (abs(I) + motor_param(SP).mIsat) - motor_param(SP).mfi0); } // ************************************************************************************************* @@ -6776,7 +6776,7 @@ double TMoverParameters::MomentumF(double I, double Iw, int SCP) { // umozliwia dokladne sterowanie wzbudzeniem - return MotorParam[SCP].mfi * I * std::max(abs(Iw) / (abs(Iw) + MotorParam[SCP].mIsat) - MotorParam[SCP].mfi0, 0.); + return motor_param(SCP).mfi * I * std::max(abs(Iw) / (abs(Iw) + motor_param(SCP).mIsat) - motor_param(SCP).mfi0, 0.); } // ************************************************************************************************* @@ -6909,7 +6909,7 @@ bool TMoverParameters::AutoRelayCheck(void) } // sprawdzenie wszystkich warunkow (AutoRelayFlag, AutoSwitch, Im VelUp) { @@ -7834,7 +7834,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void) } else dizel_EngageSwitch(0.0); - if (!(MotorParam[ScndCtrlActualPos].mIsat > 0)) + if (!(motor_param(ScndCtrlActualPos).mIsat > 0)) dizel_EngageSwitch(0.0); // wylacz sprzeglo na pozycjach neutralnych if (!AutoRelayFlag) ScndCtrlActualPos = ScndCtrlPos; @@ -7956,7 +7956,7 @@ double TMoverParameters::dizel_fillcheck(int mcp, double dt) // napelnienie zalezne od MainCtrlPos if (EIMCtrlType > 0) { - realfill = std::max(0.0, std::min(eimic_real, 1 - MotorParam[ScndCtrlActualPos].Isat)); + realfill = std::max(0.0, std::min(eimic_real, 1 - motor_param(ScndCtrlActualPos).Isat)); if (eimic_real > 0.005 && !hydro_TC_Lockup) { dizel_nreg_min = std::min(dizel_nreg_min + 2.5 * dt, dizel_nmin_hdrive + eimic_real * dizel_nmin_hdrive_factor); @@ -8044,7 +8044,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt) double Moment = 0, enMoment = 0, gearMoment = 0, eps = 0, newn = 0, friction = 0, neps = 0; double TorqueH = 0, TorqueL = 0, TorqueC = 0; n = n * CabActive; - if (MotorParam[ScndCtrlActualPos].mIsat < 0.001 || DirActive == 0) + if (motor_param(ScndCtrlActualPos).mIsat < 0.001 || DirActive == 0) n = enrot; friction = dizel_engagefriction; hydro_TC_nIn = enrot; // wal wejsciowy przetwornika momentu @@ -9079,6 +9079,17 @@ int s2NNW(std::string s) // Q: 20160717 // ************************************************************************************************* // parsowanie Motor Param Table +// checks a motor parameter table position read from the .fiz file against the table size +static bool is_valid_mpt_index(int const Index) +{ + if (Index >= 0 && Index <= MotorParametersArraySize) + { + return true; + } + WriteLog("Read MPT: position " + std::to_string(Index) + " out of range 0-" + std::to_string(MotorParametersArraySize) + " in line " + std::to_string(LISTLINE)); + return false; +} + bool TMoverParameters::readMPT0(std::string const &line) { @@ -9091,6 +9102,10 @@ bool TMoverParameters::readMPT0(std::string const &line) } int idx = 0; // numer pozycji parser >> idx; + if (false == is_valid_mpt_index(idx)) + { + return false; + } switch (EngineType) { case TEngineType::DieselEngine: @@ -9155,6 +9170,10 @@ bool TMoverParameters::readMPTElectricSeries(std::string const &line) } int idx = 0; // numer pozycji parser >> idx; + if (false == is_valid_mpt_index(idx)) + { + return false; + } parser >> MotorParam[idx].mfi >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].Isat; if (true == parser.getTokens(1, false)) { @@ -9180,6 +9199,10 @@ bool TMoverParameters::readMPTDieselElectric(std::string const &line) } int idx = 0; // numer pozycji parser >> idx; + if (false == is_valid_mpt_index(idx)) + { + return false; + } parser >> MotorParam[idx].mfi >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].Isat >> MPTRelay[idx].Iup >> MPTRelay[idx].Idown; return true; @@ -9196,6 +9219,10 @@ bool TMoverParameters::readMPTDieselEngine(std::string const &line) } int idx = 0; // numer pozycji parser >> idx; + if (false == is_valid_mpt_index(idx)) + { + return false; + } parser >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].mfi; if (true == parser.getTokens(1, false)) { @@ -11740,6 +11767,14 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) CompressorPower = 3; } + // for these engine types secondary controller positions index MotorParam table + if ((EngineType == TEngineType::ElectricSeriesMotor || EngineType == TEngineType::DieselEngine || EngineType == TEngineType::DieselElectric) && + ScndCtrlPosNo > MotorParametersArraySize) + { + WriteLog("SCPN=" + std::to_string(ScndCtrlPosNo) + " exceeds motor parameter table size, limited to " + std::to_string(MotorParametersArraySize)); + ScndCtrlPosNo = MotorParametersArraySize; + } + // WriteLog("aa = " + AxleArangement + " " + std::string( Pos("o", AxleArangement)) ); if (contains(AxleArangement, "o") && EngineType == TEngineType::ElectricSeriesMotor)