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

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

Open
misson20000 opened this issue Jan 5, 2019 · 6 comments
Open

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

misson20000 opened this issue Jan 5, 2019 · 6 comments

Comments

@misson20000
Copy link

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"
@plutooo
Copy link
Member

plutooo commented Jan 5, 2019

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

@yellows8
Copy link
Contributor

yellows8 commented Jan 5, 2019

What's the use-case for this?

@plutooo exactly

@misson20000
Copy link
Author

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

@yellows8
Copy link
Contributor

yellows8 commented Jan 5, 2019

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

@misson20000
Copy link
Author

misson20000 commented Jan 6, 2019

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.

@yellows8
Copy link
Contributor

yellows8 commented Jan 6, 2019

nvm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants