Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Ambiguous parsing of commands #260

Open
AlexRuiz7 opened this issue Feb 3, 2025 · 1 comment
Open

[BUG] Ambiguous parsing of commands #260

AlexRuiz7 opened this issue Feb 3, 2025 · 1 comment
Labels
level/task Task issue type/bug Bug issue

Comments

@AlexRuiz7
Copy link
Member

Describe the bug
I found a bug where the action is incorrectly parsed using the generic parser. This happens on commands where action.args is specified before than action.name, as action.name has not been parsed yet and the current logic in unable to determine the action type.

    public static Action parse(XContentParser parser) throws IOException, IllegalArgumentException {
        String name = "";
        Args args = new Args();
        String version = null;

        while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
            String fieldName = parser.currentName();
            parser.nextToken();
            switch (fieldName) {
                case NAME:
                    name = parser.text();
                    break;
                case Args.ARGS:
                    switch (name) {
                        case "set-group":
                            log.info("Parsing arguments for [set-group] command");
                            args = SetGroupCommand.parse(parser);
                            break;
                        case "fetch-config":
                            log.info("Parsing arguments for [fetch-config] command");
                            args = FetchConfigCommand.parse(parser);
                            break;
                        default:
                            log.info("Parsing arguments for [generic] command");
                            args = Args.parse(parser);
                            break;
                    }
                    break;
                case VERSION:
                    version = parser.text();
                    break;
                default:
                    parser.skipChildren();
                    break;
            }
        }

        return new Action(name, args, version);
    }

To Reproduce
Steps to reproduce the behavior:

🟢 Parsed as set-group, as action.name is read first.

{
  "commands": [
    {
      "action": {
        "name": "set-group",
        "args": {
          "groups": [
            "group_1",
            "group_2"
          ]
        },
        "version": "5.0.0"
      },
      "source": "Users/Services",
      "user": "Management API",
      "timeout": 100,
      "target": {
        "id": "d5b250c4-dfa1-4d94-827f-9f99210dbe6c",
        "type": "agent"
      }
    }
  ]
}

🔴 Parsed as generic, as action.args is read first.

{
  "commands": [
    {
      "action": {
        "args": {
          "groups": [
            "group_1",
            "group_2"
          ]
        },
        "name": "set-group",
        "version": "5.0.0"
      },
      "source": "Users/Services",
      "user": "Management API",
      "timeout": 100,
      "target": {
        "id": "d5b250c4-dfa1-4d94-827f-9f99210dbe6c",
        "type": "agent"
      }
    }
  ]
}

Expected behavior
Commands are parsed using the correct parsed independently of the order of the JSON data.

Plugins
Command Manager.

Additional context
Originally posted by @AlexRuiz7 in #253 (review)

@AlexRuiz7 AlexRuiz7 added level/task Task issue type/bug Bug issue labels Feb 3, 2025
@AlexRuiz7
Copy link
Member Author

We probably will need to refactor the parsing of commands to receive not only the parser but the request object, which allows better handling of the content and the creation of several copies of the parser.

request.content()

        /// Request parsing
        /// ===============
        /// Retrieves and generates an array list of commands.
        XContentParser parser = request.contentParser();
        List<Command> commands = new ArrayList<>();
        ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
        // The array of commands is inside the "commands" JSON object.
        // This line moves the parser pointer to this object.
        parser.nextToken();
        if (parser.nextToken() == XContentParser.Token.START_ARRAY) {
            commands = Command.parseToArray(parser);
        } else {
            log.error("Token does not match {}", parser.currentToken());
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
level/task Task issue type/bug Bug issue
Projects
Status: Backlog
Development

No branches or pull requests

1 participant