(ctx *ValidationContext, icon *model.Icon)
| 252 | } |
| 253 | |
| 254 | func validateIcon(ctx *ValidationContext, icon *model.Icon) *ValidationResult { |
| 255 | result := &ValidationResult{Valid: true, Issues: []ValidationIssue{}} |
| 256 | |
| 257 | // Parse the URL to ensure it's valid |
| 258 | parsedURL, err := url.Parse(icon.Src) |
| 259 | if err != nil { |
| 260 | issue := NewValidationIssueFromError( |
| 261 | ValidationIssueTypeSemantic, |
| 262 | ctx.Field("src").String(), |
| 263 | fmt.Errorf("invalid icon src URL: %w", err), |
| 264 | "icon-src-invalid-url", |
| 265 | ) |
| 266 | result.AddIssue(issue) |
| 267 | return result |
| 268 | } |
| 269 | |
| 270 | // Ensure it's an absolute URL |
| 271 | if !parsedURL.IsAbs() { |
| 272 | issue := NewValidationIssueFromError( |
| 273 | ValidationIssueTypeSemantic, |
| 274 | ctx.Field("src").String(), |
| 275 | fmt.Errorf("icon src must be an absolute URL (include scheme): %s", icon.Src), |
| 276 | "icon-src-not-absolute", |
| 277 | ) |
| 278 | result.AddIssue(issue) |
| 279 | } |
| 280 | |
| 281 | // Only allow HTTPS scheme for security (no HTTP or data: URIs) |
| 282 | if parsedURL.Scheme != SchemeHTTPS { |
| 283 | issue := NewValidationIssueFromError( |
| 284 | ValidationIssueTypeSemantic, |
| 285 | ctx.Field("src").String(), |
| 286 | fmt.Errorf("icon src must use https scheme (got %s): %s", parsedURL.Scheme, icon.Src), |
| 287 | "icon-src-invalid-scheme", |
| 288 | ) |
| 289 | result.AddIssue(issue) |
| 290 | } |
| 291 | |
| 292 | return result |
| 293 | } |
| 294 | |
| 295 | func validatePackageField(ctx *ValidationContext, obj *model.Package) *ValidationResult { |
| 296 | result := &ValidationResult{Valid: true, Issues: []ValidationIssue{}} |
no test coverage detected
searching dependent graphs…