mirror of
https://github.com/lima-vm/lima.git
synced 2026-10-29 04:04:36 +08:00
ioutilx: fail on cygpath errors instead of converting natively
The native fallback fired on every cygpath failure -- a broken install, a non-zero exit, a cancelled context -- silently substituting an MSYS-form path where an authoritative cygpath would have answered differently. Restrict the fallback to a genuinely missing cygpath binary, and return the error otherwise. Also name the /c/... form MSYS-style rather than Cygwin-style: stock Cygwin maps C:\ to /cygdrive/c/, so the label pointed at the one toolchain the form does not match. Signed-off-by: Jan Dubois <jan.dubois@suse.com>
This commit is contained in:
1 parent
21ecba913d
commit
7a5a207df0
1 file changed
+17
-10
+17
-10
@@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -59,27 +60,33 @@ func WindowsSubsystemPath(ctx context.Context, orig string) (string, error) {
|
||||
}
|
||||
|
||||
// WindowsSubsystemPathWithCygpath converts a Windows path with the given
|
||||
// cygpathExe ("cygpath" for PATH, or an absolute path to bind the
|
||||
// conversion to one Cygwin install). When cygpath is unavailable it falls
|
||||
// back to a native conversion of the drive-letter case; Universal Naming Convention
|
||||
// (UNC) and other non-drive-letter inputs return an error.
|
||||
// cygpathExe ("cygpath" for PATH, or an absolute path to bind the conversion
|
||||
// to one Cygwin install). When the cygpath binary is not found it falls back
|
||||
// to a native conversion of the absolute drive-letter case; a cygpath that
|
||||
// runs and fails returns its error, and non-drive-letter inputs (UNC, device,
|
||||
// extended-length) return an error.
|
||||
func WindowsSubsystemPathWithCygpath(ctx context.Context, cygpathExe, orig string) (string, error) {
|
||||
out, err := exec.CommandContext(ctx, cygpathExe, filepath.ToSlash(orig)).CombinedOutput()
|
||||
if err == nil {
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
}
|
||||
if !errors.Is(err, exec.ErrNotFound) && !errors.Is(err, fs.ErrNotExist) {
|
||||
return "", fmt.Errorf("failed to run %#q on %#q: %#q: %w", cygpathExe, orig, strings.TrimSpace(string(out)), err)
|
||||
}
|
||||
|
||||
logrus.WithError(err).Debugf("cygpath unavailable for %#q (output: %#q), attempting native conversion", orig, strings.TrimSpace(string(out)))
|
||||
logrus.WithError(err).Debugf("%#q not found for %#q, attempting native conversion", cygpathExe, orig)
|
||||
|
||||
return windowsSubsystemPathWithoutCygpath(orig)
|
||||
}
|
||||
|
||||
func windowsSubsystemPathWithoutCygpath(orig string) (string, error) {
|
||||
// Only an absolute drive-letter path ("C:\foo") has a well-defined
|
||||
// Cygwin form here. A drive-relative path ("C:foo") would become
|
||||
// an unrelated absolute path, so reject it.
|
||||
// The /c/... form this produces is the MSYS2 and Git-for-Windows
|
||||
// convention; stock Cygwin defaults to /cygdrive/c/. Only an absolute
|
||||
// drive-letter path ("C:\foo") has a well-defined form here. A
|
||||
// drive-relative path ("C:foo") would become an unrelated absolute
|
||||
// path, so reject it.
|
||||
if !filepath.IsAbs(orig) {
|
||||
return "", fmt.Errorf("cannot convert %#q to a Cygwin-style path: input is not an absolute drive-letter path", orig)
|
||||
return "", fmt.Errorf("cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path", orig)
|
||||
}
|
||||
|
||||
// UNC path ("\\server\share\foo") is rejected here.
|
||||
@@ -92,7 +99,7 @@ func windowsSubsystemPathWithoutCygpath(orig string) (string, error) {
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("cannot convert %#q to a Cygwin-style path: cygpath is unavailable and input is not an absolute drive-letter path", orig)
|
||||
return "", fmt.Errorf("cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path", orig)
|
||||
}
|
||||
|
||||
func WindowsSubsystemPathForLinux(ctx context.Context, orig, distro string) (string, error) {
|
||||
|
||||
Reference in new issue
Block a user