diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 39f655d..5c13610 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -745,7 +745,16 @@ class SelfdriveD(GapButtonActions): self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled") self.disengage_on_accelerator = self.params.get_bool("DisengageOnAccelerator") self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl - self.personality = self.params.get("LongitudinalPersonality", return_default=True) + # Params can be changed while selfdrived is running. Keep the live value in + # the same valid enum range enforced during startup; otherwise a stale value + # (for example 3) makes the alert callback lookup raise KeyError and kills + # selfdrived. + self.personality = get_sanitize_int_param( + "LongitudinalPersonality", + min(log.LongitudinalPersonality.schema.enumerants.values()), + max(log.LongitudinalPersonality.schema.enumerants.values()), + self.params, + ) self.nav_exit_lane_change = self._read_nav_exit_lane_change() self.model_download_pending = self.params.get("ModelManager_DownloadIndex") is not None diff --git a/selfdrive/selfdrived/tests/test_longitudinal_pref_persistence.py b/selfdrive/selfdrived/tests/test_longitudinal_pref_persistence.py index b8e1c58..ba128f7 100644 --- a/selfdrive/selfdrived/tests/test_longitudinal_pref_persistence.py +++ b/selfdrive/selfdrived/tests/test_longitudinal_pref_persistence.py @@ -1,6 +1,6 @@ from cereal import car -from openpilot.selfdrive.selfdrived.selfdrived import _cleanup_startup_params +from openpilot.selfdrive.selfdrived.selfdrived import _cleanup_startup_params, get_sanitize_int_param class DummyParams: @@ -21,3 +21,20 @@ class TestLongitudinalPrefPersistence: _cleanup_startup_params(cp, params) assert params.removed == [] + + def test_invalid_personality_is_clamped_before_use(self): + class ParamsWithInvalidPersonality: + def __init__(self): + self.value = 3 + + def get(self, key: str, return_default: bool = False) -> int: + assert key == "LongitudinalPersonality" + return self.value + + def put(self, key: str, value: int) -> None: + assert key == "LongitudinalPersonality" + self.value = value + + params = ParamsWithInvalidPersonality() + assert get_sanitize_int_param("LongitudinalPersonality", 0, 2, params) == 2 + assert params.value == 2