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

Windows escaping issues #314

Merged
merged 5 commits into from
Aug 11, 2022

Conversation

mrexox
Copy link
Member

@mrexox mrexox commented Aug 10, 2022

Closes #269

Summary 🔧

This bug is from go exec builtin package: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/os/exec/exec.go;l=269. They suggest passing args directly with syscall attrs. This is what is done with this PR.

Also fixed a thing: if the {staged_files} or any other template is quoted like "{staged_files}", all the files from substitution will be quoted. Previously the whole line was quoted, and this is not what you want on Windows, I think.

Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
@mrexox mrexox marked this pull request as ready for review August 10, 2022 08:34
Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
mrexox added 3 commits August 10, 2022 16:34
Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
@mrexox mrexox merged commit f91d56f into evilmartians:master Aug 11, 2022
@mrexox mrexox linked an issue Aug 11, 2022 that may be closed by this pull request
@mrexox mrexox added this to the 1.1.0 milestone Aug 11, 2022
@ariccio
Copy link
Contributor

ariccio commented Aug 20, 2022

Thanks for paying attention to us windows users :)

But it looks like this patch inadvertently added a regression. I'm not 100% sure what the offending change was in this commit.

I have some scripts declared in my lefthook.yml as such:

pre-push:
  parallel: true
  scripts:
    "check_validates_timeliness.rb":
      runner: ruby
    "check_if_googleauth_compat_with_heroku_22.rb":
      runner: ruby

These scripts are in a path with a space in a parent directory's name - my username! - and it looks like lefthook is no longer passing the path directly to invoke the new process. So ruby gets invoked with a path that ends at the space. lefthook eventually spits out an error like:

⠼ waitingC:/Users/Lucius:1: numeric literal without digits
[0B48:3374][2022-08-09T17:26:40]...
C:/Users/Lucius:1: syntax error, unexpected integer literal, expecting ']'
[0B48:3374][2022-08-09T17:26:40]i0...
C:/Users/Lucius:1: numeric literal without digits
[0B48:3374][2022-08-09T17:26:40]...
C:/Users/Lucius:1: syntax error, unexpected integer literal, expecting ']'
[0B48:3374][2022-08-09T17:26:40]i0...

  EXECUTE > check_validates_timeliness.rb


  EXECUTE > check_if_googleauth_compat_with_heroku_22.rb


SUMMARY: (done in 2.18 seconds)
🥊  check_validates_timeliness.rb
🥊  check_if_googleauth_compat_with_heroku_22.rb

(yes, lmao, this was my dad's computer like 10 years ago, I never changed the username)

...as seen in procmon, lefthook invokes ruby with the following unquoted command line:

ruby C:\Users\Lucius Riccio\Documents\GitHub\COVID-CO2-tracker\.lefthook\pre-push\check_validates_timeliness.rb

mimes shaking fist path names are a such a pain! :D

@mrexox
Copy link
Member Author

mrexox commented Aug 21, 2022

Hey! Thank you for the issue description! I'll check this. This is definitely fixable!

@mrexox mrexox mentioned this pull request Aug 22, 2022
@mrexox
Copy link
Member Author

mrexox commented Aug 22, 2022

Hay @ariccio , can you update to 1.1.1? This issue should be fixed there

@ariccio
Copy link
Contributor

ariccio commented Aug 22, 2022

Ok, I couldn't get to it today, and I'm working the polls tomorrow (all day! 5AM - 11pm!), But I'll try and get to it Wednesday!

@ariccio
Copy link
Contributor

ariccio commented Aug 29, 2022

Uh, I may have been stuck distracted by my family for like a week after working the polls (sshhh, don't tell them). I've updated lefthook, and am now seeing a different problem... looks like chmoding is failing.

Looks like in go on Windows, chmod just calls into SetFileAttributesW, nothing fancy going on. The path in the error message is surrounded by single quotes. Is it possible that you're now passing the quoted path to the Win32 api? That's my guess here. Honestly, it's kind of amazing we're still using text strings/command lines to do anything these days! APIs that don't need quotes are the way to go :)

@mrexox
Copy link
Member Author

mrexox commented Aug 30, 2022

Oh, I'll take a look at that issue. This is really surprising, because it's Go API, that should be working 🤔.

@ariccio
Copy link
Contributor

ariccio commented Aug 30, 2022

I'm not a go programmer, I don't think I can easily hotpatch this locally right? I suspect it's not a problem with go, but that windows doesn't like quoted paths being passed to "strongly typed" APIs (which don't need no stinkin quotes)... I think you might have been passing the newly quoted path through to the other part of the program?

@ariccio
Copy link
Contributor

ariccio commented Aug 30, 2022

I'll tell ya, as one of the few programmers out there who has made the mistake of a main user account with a space in it, nothing else has caused more pain, or uncovered more bugs, in my entire career 🤣

ariccio added a commit to ariccio/lefthook that referenced this pull request Sep 23, 2022
evilmartians#314 introduced a [regression](evilmartians#314 (comment)) that passes quoted paths to `fs.chmod`.
[`fs.Chmod`/`os.chmod` on windows](https://cs.opensource.google/go/go/+/master:src/syscall/syscall_windows.go;l=647;drc=242adb784cd64265ce803f6b0c59dbf126bcda9c) calls into the [`GetFileAttributes`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesw)/[`SetFileAttributes`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileattributesw) win32 api directly. The win32 api expects a "strongly typed" path, without quotes, unlike a command line string, and doesn't try to *parse* it. Passing quoted paths to fs.Chmod causes the operation to fail - valid paths do not begin with quotes!

This change moves the path quoting down into `runScript`, so that we can pass the UNquoted path to `fs.Chmod`.

To my great surprise, it looks like go does NOT check `GetLastError` when `GetFileAttributes`/`SetFileAttributes` fails? This is disappointing, because somewhere down the stack, procmon says windows returns "NAME INVALID", which is probably `STATUS_OBJECT_NAME_INVALID`. Poking around kernelbase.dll in GHIDRA shows a couple places where it sets last error, and you can see plenty more in the ReactOS sources.
@ariccio
Copy link
Contributor

ariccio commented Sep 23, 2022

@mrexox, I submitted a PR to fix the regression.

mrexox pushed a commit that referenced this pull request Sep 28, 2022
* Fix regression from #314 (chmod missed fix)

#314 introduced a [regression](#314 (comment)) that passes quoted paths to `fs.chmod`.
[`fs.Chmod`/`os.chmod` on windows](https://cs.opensource.google/go/go/+/master:src/syscall/syscall_windows.go;l=647;drc=242adb784cd64265ce803f6b0c59dbf126bcda9c) calls into the [`GetFileAttributes`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesw)/[`SetFileAttributes`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileattributesw) win32 api directly. The win32 api expects a "strongly typed" path, without quotes, unlike a command line string, and doesn't try to *parse* it. Passing quoted paths to fs.Chmod causes the operation to fail - valid paths do not begin with quotes!

This change moves the path quoting down into `runScript`, so that we can pass the UNquoted path to `fs.Chmod`.

To my great surprise, it looks like go does NOT check `GetLastError` when `GetFileAttributes`/`SetFileAttributes` fails? This is disappointing, because somewhere down the stack, procmon says windows returns "NAME INVALID", which is probably `STATUS_OBJECT_NAME_INVALID`. Poking around kernelbase.dll in GHIDRA shows a couple places where it sets last error, and you can see plenty more in the ReactOS sources.

* remove unused dir param.

* Move `quotedScriptPath` initialization near actual use

Believe it or not, I'm NOT a C89 programmer, I hate code that initializes variables at the top of the block. And yet, here I am. *Something something cobblers kids have no shoes something*
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

Successfully merging this pull request may close these issues.

Unable to process files with a $ in their path Bad quote escape with "git-bash" (windows)
2 participants