Skip to content

Argument parsing (& associated HBABI spec) is problematic #13

Open
@misson20000

Description

@misson20000

The Problem

As defined by the HBABI, the Argv key has an unused (formerly argc) field, and an argv field. When originally defined, it was unclear what exactly the argv field represented. I know that I personally thought the argv contained a pointer to an array of pointers to characters, and that argc was intended to indicate how long this array was.

The spec was later slightly clarified to indicate that the argv field contains a string pointer, and even later, the argc field was removed, but the argv field was left with an incomplete and ambiguous specification for how exactly arguments are separated.

The current libnx implementation separates arguments by spaces, except for when they are "quoted". I don't know if this argument parsing code was designed to patch the Nintendo implementation or not, but either way, this behavior is not defined in the HBABI spec. Additionally, this logic does not provide a mechanism to escape quotation marks and does not match the behavior of common shells (bash) when quotation marks are introduced in strange places. This means that given an argc+argv pair, there is no way to reliably encode and pass it as an HBABI key in such a way that it will be decoded back to the exact same pair.

A Solution

The current argument parsing behavior should be defined in the HBABI spec, but that doesn't address the problem of no perfect escaping. The argument parsing can't be changed without breaking compatibility, and a homebrew loader has no way of knowing whether an application will have correct argument parsing logic or not. I don't think that argument parsing should've ever been the application's job in the first place, so I'd suggest we define a new HBABI key that passes arguments in argc/argv format, avoiding the argument parsing problem altogether. Compatibility can be retained by having homebrew loaders attempt to pack argc/argv into a constant string for the old Argv key, while also passing a newer extended Argv key. The extended argv key can be marked mandatory if perfect argv packing was not possible.

Argument Parsing Inconsistency Examples

foo "" bar

Bash:

  • foo
  • (empty)
  • bar

Libnx:

  • foo
  • " ba

foo" bar"

Bash:

  • foo bar

Libnx

  • foo"
  • bar"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions