fix(cmd): improve ValidURL reliability

fixes https://github.com/containers/podman/issues/26350

Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
This commit is contained in:
axel7083
2025-06-12 14:07:16 +02:00
parent 27593b9e33
commit d680c48eaf
4 changed files with 81 additions and 8 deletions

View File

@ -130,7 +130,7 @@ func importCon(cmd *cobra.Command, args []string) error {
}
errFileName := parse.ValidateFileName(source)
errURL := parse.ValidURL(source)
errURL := parse.ValidWebURL(source)
if errURL == nil {
importOpts.SourceIsURL = true
}

View File

@ -369,7 +369,7 @@ func readerFromArg(fileName string) (*bytes.Reader, error) {
switch {
case fileName == "-": // Read from stdin
reader = os.Stdin
case parse.ValidURL(fileName) == nil:
case parse.ValidWebURL(fileName) == nil:
response, err := http.Get(fileName)
if err != nil {
return nil, err

View File

@ -157,14 +157,21 @@ func parseEnvOrLabelFile(envOrLabel map[string]string, filename, configType stri
return scanner.Err()
}
// ValidURL checks a string urlStr is a url or not
func ValidURL(urlStr string) error {
url, err := url.ParseRequestURI(urlStr)
// ValidWebURL checks a string urlStr is a url or not
func ValidWebURL(urlStr string) error {
parsedURL, err := url.ParseRequestURI(urlStr)
if err != nil {
return fmt.Errorf("invalid url %q: %w", urlStr, err)
return fmt.Errorf("invalid URL %q: %w", urlStr, err)
}
if url.Scheme == "" {
return fmt.Errorf("invalid url %q: missing scheme", urlStr)
// to be a valid web url, scheme must be either http or https
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
return fmt.Errorf("invalid URL %q: unsupported scheme %q", urlStr, parsedURL.Scheme)
}
// ensure url contain a host
if parsedURL.Host == "" {
return fmt.Errorf("invalid URL %q: missing host", urlStr)
}
return nil
}

View File

@ -158,3 +158,69 @@ func TestGetAllLabelsFile(t *testing.T) {
result, _ := GetAllLabels(fileLabels, Var1)
assert.Equal(t, len(result), 3)
}
func TestValidWebURL(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{
name: "Valid HTTP URL",
input: "http://example.com",
wantErr: false,
},
{
name: "Valid HTTPS URL",
input: "https://example.com",
wantErr: false,
},
{
name: "Missing scheme",
input: "example.com",
wantErr: true,
},
{
name: "Unsupported scheme - FTP",
input: "ftp://example.com",
wantErr: true,
},
{
name: "Missing host",
input: "https://",
wantErr: true,
},
{
name: "Local file path - Windows style",
input: "C:/hello/world",
wantErr: true,
},
{
name: "Local file path - Unix style",
input: "/usr/local/bin",
wantErr: true,
},
{
name: "Invalid URL characters",
input: "https://example.com/%%%",
wantErr: true,
},
{
name: "Valid URL with port",
input: "https://example.com:8080",
wantErr: false,
},
{
name: "Valid URL with path",
input: "https://example.com/path/to/resource",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidWebURL(tt.input)
assert.Equal(t, tt.wantErr, err != nil, "ValidWebURL(%q) = %v, wantErr %v", tt.input, err, tt.wantErr)
})
}
}