From bb08b9d01722156eaeea0e0f3b979a06ff171deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 29 Jul 2026 20:16:56 +0200 Subject: [PATCH] fix(config): validate configuration activation SetConfig and ReadConfig returned success when libGammu rejected the active configuration count, deferring the failure until initialization. Closes gammu/gammu#414 --- gammu/src/gammu.c | 24 ++++++++++++++++++++---- test/test_config.py | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/gammu/src/gammu.c b/gammu/src/gammu.c index 38b0d5fc0..908e8bbf8 100644 --- a/gammu/src/gammu.c +++ b/gammu/src/gammu.c @@ -554,6 +554,20 @@ StateMachine_GetConfig(StateMachineObject *self, PyObject *args, PyObject *kwds) "UseGlobalDebugFile", Config->UseGlobalDebugFile); } +static int +StateMachine_ActivateConfig(StateMachineObject *self, int section) +{ + if (GSM_GetConfigNum(self->s) <= section) { + GSM_SetConfigNum(self->s, section + 1); + if (GSM_GetConfigNum(self->s) <= section) { + PyErr_Format(PyExc_ValueError, "Maximal configuration storage exceeded"); + return 0; + } + } + + return 1; +} + static char StateMachine_SetConfig__doc__[] = "SetConfig(Section, Values)\n\n" "Sets specified config section.\n\n" @@ -688,8 +702,8 @@ StateMachine_SetConfig(StateMachineObject *self, PyObject *args, PyObject *kwds) } } - /* Tell Gammu we have configured another section */ - GSM_SetConfigNum(self->s, section + 1); + if (!StateMachine_ActivateConfig(self, section)) + return NULL; Py_RETURN_NONE; } @@ -746,8 +760,10 @@ StateMachine_ReadConfig(StateMachineObject *self, PyObject *args, PyObject *kwds } Config->UseGlobalDebugFile = FALSE; - /* Tell Gammu we have configured another section */ - GSM_SetConfigNum(self->s, dst + 1); + if (!StateMachine_ActivateConfig(self, dst)) { + INI_Free(cfg); + return NULL; + } INI_Free(cfg); diff --git a/test/test_config.py b/test/test_config.py index e78ea93d9..6d3aa7606 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -30,6 +30,28 @@ class ConfigTest(unittest.TestCase): + def test_config_sections(self) -> None: + with tempfile.TemporaryDirectory() as temp_dir: + config_file = Path(temp_dir) / "gammurc" + config_file.write_text( + "[gammu4]\nconnection = none\ndevice = /dev/null\n", + encoding="utf-8", + ) + + state_machine = gammu.StateMachine() + state_machine.ReadConfig(Section=4, Filename=str(config_file)) + state_machine.SetConfig(0, state_machine.GetConfig(4)) + + cfg = state_machine.GetConfig(4) + assert cfg["Connection"] == "none" + assert cfg["Device"] == "/dev/null" + + with pytest.raises( + ValueError, + match="Requested configuration not available", + ): + state_machine.GetConfig(100) + def test_config_bool(self) -> None: state_machine = gammu.StateMachine() state_machine.SetConfig(