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

cmcfarlen pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 28400bb8376ae6f4ba0802207e9d0ece400e3738
Author: Damian Meden <[email protected]>
AuthorDate: Mon Oct 27 21:29:53 2025 +0100

    Fix ArgParser command disambiguation to prevent args being treated as 
commands (#12598)
    
    * Fix ArgParser command disambiguation to prevent args being treated as 
commands
    
    Fixes issue where any argument matching a command name would trigger
    incorrect "No subcommand found" errors.
    
    (cherry picked from commit da027ef35e255e8f638b179035c67a9df48ce828)
---
 src/tscore/ArgParser.cc | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/tscore/ArgParser.cc b/src/tscore/ArgParser.cc
index d863a3cc25..c7b474c889 100644
--- a/src/tscore/ArgParser.cc
+++ b/src/tscore/ArgParser.cc
@@ -504,26 +504,28 @@ bool
 ArgParser::Command::parse(Arguments &ret, AP_StrVec &args)
 {
   bool command_called = false;
-  // iterate through all arguments
-  for (unsigned i = 0; i < args.size(); i++) {
-    if (_name == args[i]) {
-      command_called = true;
-      // handle the option
-      append_option_data(ret, args, i);
-      // handle the action
-      if (_f) {
-        ret._action = _f;
-      }
-      std::string err = handle_args(ret, args, _key, _arg_num, i);
-      if (!err.empty()) {
-        help_message(err);
-      }
-      // set ENV var
-      if (!_envvar.empty()) {
-        const char *const env = getenv(_envvar.c_str());
-        ret.set_env(_key, nullptr != env ? env : "");
-      }
-      break;
+  // Only check the first remaining argument for command name to avoid
+  // treating arguments as commands (e.g., "metric match host" where "host" is 
an arg, not a command)
+  if (!args.empty() && _name == args[0]) {
+    command_called = true;
+    // Note: handle_args modifies its index parameter (designed for loop 
usage), but we
+    // discard the result. This causes unsigned underflow (0 - 1 = UINT_MAX) 
which is
+    // harmless since we don't use index afterward.
+    unsigned index{0};
+    // handle the option
+    append_option_data(ret, args, index);
+    // handle the action
+    if (_f) {
+      ret._action = _f;
+    }
+    const std::string err = handle_args(ret, args, _key, _arg_num, index);
+    if (!err.empty()) {
+      help_message(err);
+    }
+    // set ENV var
+    if (!_envvar.empty()) {
+      const char *const env = getenv(_envvar.c_str());
+      ret.set_env(_key, nullptr != env ? env : "");
     }
   }
   if (command_called) {

Reply via email to