From 385336432b58cd1c57b9f065d6aeea19cccedd13 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:58:53 +0000 Subject: [PATCH 1/7] Initial plan From ffa6756f4e50af1a8da059b2abbb1747459227f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 17:08:12 +0000 Subject: [PATCH 2/7] fix: URL-escape placeholder values in BuildLookasideURL and add BuildDistGitURL Apply url.PathEscape() to all placeholder values before substitution in BuildLookasideURL so reserved URL characters (/, ?, #, %) don't alter URL structure. Parse and validate the final URL before returning. Create BuildDistGitURL for dist-git URL construction with the same path-escaping and validation protections. Update the two raw strings.ReplaceAll call sites in fedorasourceprovider.go to use the new function. Add comprehensive test coverage for both functions with reserved URL characters in filename and packageName inputs. Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/c56e9983-31d5-4a6d-9ac6-e6fee388466f Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../fedorasource/fedorasource.go | 44 ++++++- .../fedorasource/fedorasource_test.go | 113 ++++++++++++++++++ .../sourceproviders/fedorasourceprovider.go | 11 +- 3 files changed, 160 insertions(+), 8 deletions(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index 9029ffc2..d8e94804 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "log/slog" + "net/url" "path/filepath" "regexp" "strings" @@ -314,8 +315,12 @@ const ( // [PlaceholderFilename], [PlaceholderHashType], and [PlaceholderHash]. // Placeholders not present in the template are simply ignored. // +// Substituted values are URL path-escaped via [url.PathEscape] so that reserved +// characters such as /, ?, #, and % do not alter the URL structure. +// // Returns an error if any of the provided values contain a placeholder string, as this -// would cause ambiguous substitution results depending on replacement order. +// would cause ambiguous substitution results depending on replacement order, or if the +// resulting URL is not valid. func BuildLookasideURL(template, packageName, fileName, hashType, hash string) (string, error) { // allPlaceholders lists all supported lookaside URI template placeholders. allPlaceholders := []string{PlaceholderPkg, PlaceholderFilename, PlaceholderHashType, PlaceholderHash} @@ -329,10 +334,39 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( } uri := template - uri = strings.ReplaceAll(uri, PlaceholderPkg, packageName) - uri = strings.ReplaceAll(uri, PlaceholderFilename, fileName) - uri = strings.ReplaceAll(uri, PlaceholderHashType, strings.ToLower(hashType)) - uri = strings.ReplaceAll(uri, PlaceholderHash, hash) + uri = strings.ReplaceAll(uri, PlaceholderPkg, url.PathEscape(packageName)) + uri = strings.ReplaceAll(uri, PlaceholderFilename, url.PathEscape(fileName)) + uri = strings.ReplaceAll(uri, PlaceholderHashType, url.PathEscape(strings.ToLower(hashType))) + uri = strings.ReplaceAll(uri, PlaceholderHash, url.PathEscape(hash)) + + _, err := url.Parse(uri) + if err != nil { + return "", fmt.Errorf("resulting lookaside URL is not valid:\n%w", err) + } + + return uri, nil +} + +// BuildDistGitURL constructs a dist-git repository URL by substituting the +// [PlaceholderPkg] placeholder in the URI template with the provided package name. +// +// The package name is URL path-escaped via [url.PathEscape] so that reserved +// characters such as /, ?, #, and % do not alter the URL structure. +// +// Returns an error if the package name contains a placeholder string, or if the +// resulting URL is not valid. +func BuildDistGitURL(template, packageName string) (string, error) { + if strings.Contains(packageName, PlaceholderPkg) { + return "", fmt.Errorf("package name %#q contains placeholder %s, which would cause ambiguous substitution", + packageName, PlaceholderPkg) + } + + uri := strings.ReplaceAll(template, PlaceholderPkg, url.PathEscape(packageName)) + + _, err := url.Parse(uri) + if err != nil { + return "", fmt.Errorf("resulting dist-git URL is not valid:\n%w", err) + } return uri, nil } diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go index 2249196a..9c908ec1 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go @@ -326,6 +326,60 @@ func TestBuildLookasideURL(t *testing.T) { hash: "abc123", expectedError: "ambiguous substitution", }, + { + name: "filename with slash is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "foo/bar", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/my-pkg/foo%2Fbar/sha512/abc123", + }, + { + name: "filename with question mark is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "file?x=1", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/my-pkg/file%3Fx=1/sha512/abc123", + }, + { + name: "filename with hash is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "file#frag", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/my-pkg/file%23frag/sha512/abc123", + }, + { + name: "filename with malformed percent is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "file%zz", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/my-pkg/file%25zz/sha512/abc123", + }, + { + name: "packageName with slash is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "foo/bar", + filename: "source.tar.gz", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/foo%2Fbar/source.tar.gz/sha512/abc123", + }, + { + name: "packageName with hash is path-escaped", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "foo#bar", + filename: "source.tar.gz", + hashType: "SHA512", + hash: "abc123", + expected: "https://example.com/foo%23bar/source.tar.gz/sha512/abc123", + }, } for _, testCase := range tests { @@ -342,3 +396,62 @@ func TestBuildLookasideURL(t *testing.T) { }) } } + +func TestBuildDistGitURL(t *testing.T) { + tests := []struct { + name string + template string + pkg string + expected string + expectedError string + }{ + { + name: "standard template", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "curl", + expected: "https://src.example.com/rpms/curl.git", + }, + { + name: "packageName containing $pkg placeholder", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "evil-$pkg-name", + expectedError: "ambiguous substitution", + }, + { + name: "packageName with slash is path-escaped", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "foo/bar", + expected: "https://src.example.com/rpms/foo%2Fbar.git", + }, + { + name: "packageName with hash is path-escaped", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "foo#bar", + expected: "https://src.example.com/rpms/foo%23bar.git", + }, + { + name: "packageName with question mark is path-escaped", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "foo?bar", + expected: "https://src.example.com/rpms/foo%3Fbar.git", + }, + { + name: "packageName with malformed percent is path-escaped", + template: "https://src.example.com/rpms/$pkg.git", + pkg: "foo%zz", + expected: "https://src.example.com/rpms/foo%25zz.git", + }, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + result, err := BuildDistGitURL(testCase.template, testCase.pkg) + if testCase.expectedError != "" { + assert.ErrorContains(t, err, testCase.expectedError) + } else { + require.NoError(t, err) + assert.Equal(t, testCase.expected, result) + } + }) + } +} diff --git a/internal/providers/sourceproviders/fedorasourceprovider.go b/internal/providers/sourceproviders/fedorasourceprovider.go index d99338a7..00c69ff2 100644 --- a/internal/providers/sourceproviders/fedorasourceprovider.go +++ b/internal/providers/sourceproviders/fedorasourceprovider.go @@ -9,7 +9,6 @@ import ( "fmt" "log/slog" "path/filepath" - "strings" "time" "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/components" @@ -106,7 +105,10 @@ func (g *FedoraSourcesProviderImpl) GetComponent( return errors.New("destination path cannot be empty") } - gitRepoURL := strings.ReplaceAll(g.distroGitBaseURI, "$pkg", upstreamNameToUse) + gitRepoURL, err := fedorasource.BuildDistGitURL(g.distroGitBaseURI, upstreamNameToUse) + if err != nil { + return fmt.Errorf("failed to build dist-git URL for %#q:\n%w", upstreamNameToUse, err) + } slog.Info("Getting component from git repo", "component", componentName, @@ -259,7 +261,10 @@ func (g *FedoraSourcesProviderImpl) ResolveIdentity( upstreamName = component.GetName() } - gitRepoURL := strings.ReplaceAll(g.distroGitBaseURI, "$pkg", upstreamName) + gitRepoURL, err := fedorasource.BuildDistGitURL(g.distroGitBaseURI, upstreamName) + if err != nil { + return "", fmt.Errorf("failed to build dist-git URL for %#q:\n%w", upstreamName, err) + } return g.resolveCommit(ctx, gitRepoURL, upstreamName, component.GetConfig().Spec.UpstreamCommit) } From 9192372a9e4831e35770a4df05761f0ac322f9a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:54:04 +0000 Subject: [PATCH 3/7] fix: validate lowercased hashType against placeholders in BuildLookasideURL The placeholder-in-value guard checked raw hashType but substitution uses strings.ToLower(hashType). This meant hashType="$PKG" bypassed the guard and was substituted as "$pkg" (matching PlaceholderPkg). Check the normalized (lowercased) hashType against placeholders to close this bypass. Add test case for the scenario. Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/ac27db32-1692-4bde-bb94-c7c0b4f0fa5d Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../sourceproviders/fedorasource/fedorasource.go | 3 ++- .../sourceproviders/fedorasource/fedorasource_test.go | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index d8e94804..85c65b5d 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -325,7 +325,8 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( // allPlaceholders lists all supported lookaside URI template placeholders. allPlaceholders := []string{PlaceholderPkg, PlaceholderFilename, PlaceholderHashType, PlaceholderHash} - for _, v := range []string{packageName, fileName, hashType, hash} { + // Check the normalized (lowercased) hashType since that is the form actually substituted. + for _, v := range []string{packageName, fileName, strings.ToLower(hashType), hash} { for _, p := range allPlaceholders { if strings.Contains(v, p) { return "", fmt.Errorf("value %#q contains placeholder %s, which would cause ambiguous substitution", v, p) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go index 9c908ec1..e85fdb17 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go @@ -380,6 +380,15 @@ func TestBuildLookasideURL(t *testing.T) { hash: "abc123", expected: "https://example.com/foo%23bar/source.tar.gz/sha512/abc123", }, + { + name: "hashType containing uppercase placeholder is caught after lowercasing", + template: "https://example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "source.tar.gz", + hashType: "$PKG", + hash: "abc123", + expectedError: "ambiguous substitution", + }, } for _, testCase := range tests { From 456d6821008e0e4ec1162d9b42b9f7d122de6c00 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:14:59 +0000 Subject: [PATCH 4/7] fix: validate scheme and host in constructed URLs Replace the validateAbsoluteURL helper with inline validation per reviewer suggestion: url.Parse() for syntax, then check u.Scheme and u.Host are non-empty. This catches misconfigured templates (e.g. missing scheme) that url.Parse alone would silently accept. Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/661f751e-7043-4004-9580-01a1ea6036f3 Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../sourceproviders/fedorasource/fedorasource.go | 12 ++++++++++-- .../fedorasource/fedorasource_test.go | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index 85c65b5d..471bf0c7 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -340,11 +340,15 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( uri = strings.ReplaceAll(uri, PlaceholderHashType, url.PathEscape(strings.ToLower(hashType))) uri = strings.ReplaceAll(uri, PlaceholderHash, url.PathEscape(hash)) - _, err := url.Parse(uri) + u, err := url.Parse(uri) if err != nil { return "", fmt.Errorf("resulting lookaside URL is not valid:\n%w", err) } + if u.Scheme == "" || u.Host == "" { + return "", fmt.Errorf("resulting lookaside URL %#q is missing scheme or host", uri) + } + return uri, nil } @@ -364,10 +368,14 @@ func BuildDistGitURL(template, packageName string) (string, error) { uri := strings.ReplaceAll(template, PlaceholderPkg, url.PathEscape(packageName)) - _, err := url.Parse(uri) + u, err := url.Parse(uri) if err != nil { return "", fmt.Errorf("resulting dist-git URL is not valid:\n%w", err) } + if u.Scheme == "" || u.Host == "" { + return "", fmt.Errorf("resulting dist-git URL %#q is missing scheme or host", uri) + } + return uri, nil } diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go index e85fdb17..afa45e72 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource_test.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource_test.go @@ -389,6 +389,15 @@ func TestBuildLookasideURL(t *testing.T) { hash: "abc123", expectedError: "ambiguous substitution", }, + { + name: "template without scheme is rejected", + template: "example.com/$pkg/$filename/$hashtype/$hash", + pkg: "my-pkg", + filename: "source.tar.gz", + hashType: "SHA512", + hash: "abc123", + expectedError: "missing scheme or host", + }, } for _, testCase := range tests { @@ -450,6 +459,12 @@ func TestBuildDistGitURL(t *testing.T) { pkg: "foo%zz", expected: "https://src.example.com/rpms/foo%25zz.git", }, + { + name: "template without scheme is rejected", + template: "example.com/rpms/$pkg.git", + pkg: "curl", + expectedError: "missing scheme or host", + }, } for _, testCase := range tests { From 8eb81c142f3a0c0c2e46466c09644a3eef06bfb8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:33:47 +0000 Subject: [PATCH 5/7] fix: normalize hashType once and use %#q for placeholders in errors Address PawelWMS's review nit-picks: - Normalize hashType with strings.ToLower() once at the top of BuildLookasideURL instead of calling it twice - Use %#q instead of %s for placeholder values in error messages for consistency with other format verbs in the same messages Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/577c691c-31b1-42bc-8827-4f7cdad70ddd Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../sourceproviders/fedorasource/fedorasource.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index 471bf0c7..38e870f0 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -325,11 +325,13 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( // allPlaceholders lists all supported lookaside URI template placeholders. allPlaceholders := []string{PlaceholderPkg, PlaceholderFilename, PlaceholderHashType, PlaceholderHash} - // Check the normalized (lowercased) hashType since that is the form actually substituted. - for _, v := range []string{packageName, fileName, strings.ToLower(hashType), hash} { + // Normalize hashType to lowercase since that is the form actually substituted. + hashType = strings.ToLower(hashType) + + for _, v := range []string{packageName, fileName, hashType, hash} { for _, p := range allPlaceholders { if strings.Contains(v, p) { - return "", fmt.Errorf("value %#q contains placeholder %s, which would cause ambiguous substitution", v, p) + return "", fmt.Errorf("value %#q contains placeholder %#q, which would cause ambiguous substitution", v, p) } } } @@ -337,7 +339,7 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( uri := template uri = strings.ReplaceAll(uri, PlaceholderPkg, url.PathEscape(packageName)) uri = strings.ReplaceAll(uri, PlaceholderFilename, url.PathEscape(fileName)) - uri = strings.ReplaceAll(uri, PlaceholderHashType, url.PathEscape(strings.ToLower(hashType))) + uri = strings.ReplaceAll(uri, PlaceholderHashType, url.PathEscape(hashType)) uri = strings.ReplaceAll(uri, PlaceholderHash, url.PathEscape(hash)) u, err := url.Parse(uri) @@ -362,7 +364,7 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( // resulting URL is not valid. func BuildDistGitURL(template, packageName string) (string, error) { if strings.Contains(packageName, PlaceholderPkg) { - return "", fmt.Errorf("package name %#q contains placeholder %s, which would cause ambiguous substitution", + return "", fmt.Errorf("package name %#q contains placeholder %#q, which would cause ambiguous substitution", packageName, PlaceholderPkg) } From e6344c6487c29d2578ed892dc6f4b90abb53e012 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:50:55 +0000 Subject: [PATCH 6/7] refactor: extract validateAbsoluteURL helper for URL validation Extract the duplicated url.Parse + scheme/host validation into a shared validateAbsoluteURL helper used by both BuildLookasideURL and BuildDistGitURL. Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/a9b06a03-7631-4307-a461-8a366892b221 Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../fedorasource/fedorasource.go | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index 38e870f0..4436d896 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -321,6 +321,22 @@ const ( // Returns an error if any of the provided values contain a placeholder string, as this // would cause ambiguous substitution results depending on replacement order, or if the // resulting URL is not valid. +// validateAbsoluteURL parses uri and verifies it is an absolute URL with a +// non-empty scheme and host. The label parameter is used in error messages to +// identify the URL's purpose (e.g. "lookaside", "dist-git"). +func validateAbsoluteURL(uri, label string) error { + u, err := url.Parse(uri) + if err != nil { + return fmt.Errorf("resulting %s URL is not valid:\n%w", label, err) + } + + if u.Scheme == "" || u.Host == "" { + return fmt.Errorf("resulting %s URL %#q is missing scheme or host", label, uri) + } + + return nil +} + func BuildLookasideURL(template, packageName, fileName, hashType, hash string) (string, error) { // allPlaceholders lists all supported lookaside URI template placeholders. allPlaceholders := []string{PlaceholderPkg, PlaceholderFilename, PlaceholderHashType, PlaceholderHash} @@ -342,13 +358,8 @@ func BuildLookasideURL(template, packageName, fileName, hashType, hash string) ( uri = strings.ReplaceAll(uri, PlaceholderHashType, url.PathEscape(hashType)) uri = strings.ReplaceAll(uri, PlaceholderHash, url.PathEscape(hash)) - u, err := url.Parse(uri) - if err != nil { - return "", fmt.Errorf("resulting lookaside URL is not valid:\n%w", err) - } - - if u.Scheme == "" || u.Host == "" { - return "", fmt.Errorf("resulting lookaside URL %#q is missing scheme or host", uri) + if err := validateAbsoluteURL(uri, "lookaside"); err != nil { + return "", err } return uri, nil @@ -370,13 +381,8 @@ func BuildDistGitURL(template, packageName string) (string, error) { uri := strings.ReplaceAll(template, PlaceholderPkg, url.PathEscape(packageName)) - u, err := url.Parse(uri) - if err != nil { - return "", fmt.Errorf("resulting dist-git URL is not valid:\n%w", err) - } - - if u.Scheme == "" || u.Host == "" { - return "", fmt.Errorf("resulting dist-git URL %#q is missing scheme or host", uri) + if err := validateAbsoluteURL(uri, "dist-git"); err != nil { + return "", err } return uri, nil From a5bda4cfdba69ad1f04707f3c09c95e964ae6815 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 8 Apr 2026 20:25:46 +0000 Subject: [PATCH 7/7] fix: separate validateAbsoluteURL and BuildLookasideURL doc comments Move the BuildLookasideURL doc comment to directly precede its function declaration, so it is no longer merged with the validateAbsoluteURL comment block. Agent-Logs-Url: https://github.com/microsoft/azure-linux-dev-tools/sessions/30580b36-4aef-450d-ad65-a38597d233ec Co-authored-by: dmcilvaney <23200982+dmcilvaney@users.noreply.github.com> --- .../fedorasource/fedorasource.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/providers/sourceproviders/fedorasource/fedorasource.go b/internal/providers/sourceproviders/fedorasource/fedorasource.go index 4436d896..c0489e4e 100644 --- a/internal/providers/sourceproviders/fedorasource/fedorasource.go +++ b/internal/providers/sourceproviders/fedorasource/fedorasource.go @@ -310,17 +310,6 @@ const ( PlaceholderHash = "$hash" ) -// BuildLookasideURL constructs a lookaside cache URL by substituting placeholders in the -// URI template with the provided values. Supported placeholders are [PlaceholderPkg], -// [PlaceholderFilename], [PlaceholderHashType], and [PlaceholderHash]. -// Placeholders not present in the template are simply ignored. -// -// Substituted values are URL path-escaped via [url.PathEscape] so that reserved -// characters such as /, ?, #, and % do not alter the URL structure. -// -// Returns an error if any of the provided values contain a placeholder string, as this -// would cause ambiguous substitution results depending on replacement order, or if the -// resulting URL is not valid. // validateAbsoluteURL parses uri and verifies it is an absolute URL with a // non-empty scheme and host. The label parameter is used in error messages to // identify the URL's purpose (e.g. "lookaside", "dist-git"). @@ -337,6 +326,17 @@ func validateAbsoluteURL(uri, label string) error { return nil } +// BuildLookasideURL constructs a lookaside cache URL by substituting placeholders in the +// URI template with the provided values. Supported placeholders are [PlaceholderPkg], +// [PlaceholderFilename], [PlaceholderHashType], and [PlaceholderHash]. +// Placeholders not present in the template are simply ignored. +// +// Substituted values are URL path-escaped via [url.PathEscape] so that reserved +// characters such as /, ?, #, and % do not alter the URL structure. +// +// Returns an error if any of the provided values contain a placeholder string, as this +// would cause ambiguous substitution results depending on replacement order, or if the +// resulting URL is not valid. func BuildLookasideURL(template, packageName, fileName, hashType, hash string) (string, error) { // allPlaceholders lists all supported lookaside URI template placeholders. allPlaceholders := []string{PlaceholderPkg, PlaceholderFilename, PlaceholderHashType, PlaceholderHash}