nx-hbloader icon indicating copy to clipboard operation
nx-hbloader copied to clipboard

Argument parsing (& associated HBABI spec) is problematic

Open misson20000 opened this issue 5 years ago • 6 comments

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"

misson20000 avatar Jan 05 '19 00:01 misson20000

I believe the libnx argv parsing is equivalent to what Nintendo does for its "loader-based argv", but I could be wrong on that. Anyway that's what we were trying to emulate

plutooo avatar Jan 05 '19 11:01 plutooo

What's the use-case for this?

@plutooo exactly

yellows8 avatar Jan 05 '19 15:01 yellows8

Use case is perfectly forwarding arguments from a command line to a homebrew (like nxlink tries to do)

misson20000 avatar Jan 05 '19 21:01 misson20000

Perhaps you could just use: strncpy(tmpbuf, envGetArgv(), ...)

yellows8 avatar Jan 05 '19 21:01 yellows8

What? I'm not sure what you're suggesting there. I want to have a command line tool that passes its arguments (already parsed by the shell), over some kind of connection, to a program on the switch which can pass those arguments as an HBABI key to any homebrew application, without altering the arguments themselves at all.

misson20000 avatar Jan 06 '19 00:01 misson20000

nvm

yellows8 avatar Jan 06 '19 00:01 yellows8