This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nuttx-ntfc.git


The following commit(s) were added to refs/heads/main by this push:
     new 272cdc8  core: refuse commands longer than the target line buffer
272cdc8 is described below

commit 272cdc814b864f6542c92f21718ecff40d6969b8
Author: raiden00pl <[email protected]>
AuthorDate: Mon Oct 12 16:03:24 2026 +0200

    core: refuse commands longer than the target line buffer
---
 CHANGES.md                           |  1 +
 Documentation/writing-test-cases.rst |  4 +++-
 src/ntfc/core.py                     | 24 ++++++++++++++++++++++++
 tests/test_core.py                   | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 408554e..56f7b7b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,7 @@
 ## Unreleased
 
 - Add Renode device support.
+- Refuse commands longer than the target CONFIG_LINE_MAX.
 
 ## 0.0.3
 
diff --git a/Documentation/writing-test-cases.rst 
b/Documentation/writing-test-cases.rst
index 1f3a30e..cce9e14 100644
--- a/Documentation/writing-test-cases.rst
+++ b/Documentation/writing-test-cases.rst
@@ -201,7 +201,9 @@ Decorators:
   enabled
 
 The :meth:`~ntfc.products.ProductsHandler.sendCommand` method handles
-execution and verification.
+execution and verification. A command that does not fit the target shell
+line buffer (``CONFIG_LINE_MAX`` minus one character) is refused with a
+``ValueError`` instead of being split by the shell.
 
 Parametrized Command Test
 --------------------------
diff --git a/src/ntfc/core.py b/src/ntfc/core.py
index 9de18fc..8f2ddc5 100644
--- a/src/ntfc/core.py
+++ b/src/ntfc/core.py
@@ -127,6 +127,28 @@ class ProductCore:
             matched = matched.decode("utf-8", errors="ignore")
         return self._device.no_cmd in matched
 
+    def _check_line_max(self, cmd: bytes) -> None:
+        """Refuse a command the target shell cannot buffer in one line.
+
+        NSH reads at most ``CONFIG_LINE_MAX - 1`` characters per line and
+        executes the overflow as a second command, which fails in
+        confusing ways. The limit is only known when the Kconfig of the
+        image is available.
+
+        :param cmd: Encoded command including its line terminator.
+        :raises ValueError: Command does not fit the target line buffer.
+        """
+        limit = self._conf.kv_check("CONFIG_LINE_MAX")
+        if not limit:
+            return
+        length = len(cmd.rstrip(b"\r\n"))
+        if length >= int(limit):
+            raise ValueError(
+                f"command is {length} characters, the target buffers at "
+                f"most {int(limit) - 1} (CONFIG_LINE_MAX={limit}): "
+                f"{cmd.decode(errors='replace').strip()!r}"
+            )
+
     def sendCommand(  # noqa: N802
         self,
         cmd: str,
@@ -162,6 +184,7 @@ class ProductCore:
         encoded = self._builder.build(
             cmd, expects, args, flag, match_all, regexp, fail_pattern
         )
+        self._check_line_max(encoded.cmd)
 
         logger.debug(
             f"Sending command: {encoded.cmd.decode()}, expecting: "
@@ -204,6 +227,7 @@ class ProductCore:
         :return: CmdReturn : command return data
         """
         encoded = self._builder.build_raw(cmd, pattern, args, fail_pattern)
+        self._check_line_max(encoded.cmd)
 
         logger.debug(
             f"Sending command: {encoded.cmd.decode()}, expecting pattern: "
diff --git a/tests/test_core.py b/tests/test_core.py
index 7439831..1b4990b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -25,6 +25,7 @@ import pytest
 
 from ntfc.core import CoreStatus, ProductCore
 from ntfc.device.common import CmdReturn, CmdStatus
+from ntfc.envconfig import EnvConfig
 
 
 def test_core_init(envconfig_dummy):
@@ -102,6 +103,40 @@ def test_core_send_command(envconfig_dummy):
         assert p.sendCommand("test") == CmdStatus.NOTFOUND
 
 
+def test_core_rejects_command_longer_than_line_max(config_sim):
+    """A command the shell cannot buffer is refused instead of split."""
+
+    with patch("ntfc.device.common.DeviceCommon") as mockdevice:
+        dev = mockdevice.return_value
+        dev.prompt = b"NSH> "
+        dev.no_cmd = "command not found"
+        dev.send_cmd_read_until_pattern.return_value = CmdReturn(
+            CmdStatus.SUCCESS
+        )
+        core = EnvConfig(config_sim).product[0].cfg_core(0)
+        assert core.kv_check("CONFIG_LINE_MAX") == 80
+        p = ProductCore(dev, core)
+
+        assert p.sendCommand("x" * 79) == CmdStatus.SUCCESS
+        with pytest.raises(ValueError, match="CONFIG_LINE_MAX"):
+            p.sendCommand("x" * 80)
+        with pytest.raises(ValueError, match="CONFIG_LINE_MAX"):
+            p.sendCommandReadUntilPattern("x" * 70, args=["y" * 10])
+
+
+def test_core_line_max_unknown_is_not_checked(envconfig_dummy):
+
+    with patch("ntfc.device.common.DeviceCommon") as mockdevice:
+        dev = mockdevice.return_value
+        dev.prompt = b"NSH> "
+        dev.no_cmd = "command not found"
+        dev.send_cmd_read_until_pattern.return_value = CmdReturn(
+            CmdStatus.SUCCESS
+        )
+        p = ProductCore(dev, envconfig_dummy.product[0].cfg_core(0))
+        assert p.sendCommand("x" * 500) == CmdStatus.SUCCESS
+
+
 def test_core_send_command_read_until_pattern(envconfig_dummy):
     with patch("ntfc.device.common.DeviceCommon") as mockdevice:
         dev = mockdevice.return_value

Reply via email to