(reader *zip.Reader, id string, version string, goos string)
| 316 | } |
| 317 | |
| 318 | func readTargetLibrary(reader *zip.Reader, id string, version string, goos string) ([]byte, os.FileMode, error) { |
| 319 | targetName := strings.TrimSpace(id) + pluginExtension(goos) |
| 320 | versionedTargetName := versionedPluginFileName(id, version, goos) |
| 321 | var target *zip.File |
| 322 | for _, file := range reader.File { |
| 323 | cleanedName, errClean := cleanZipName(file.Name) |
| 324 | if errClean != nil { |
| 325 | return nil, 0, errClean |
| 326 | } |
| 327 | if file.FileInfo().IsDir() { |
| 328 | continue |
| 329 | } |
| 330 | if !regularZipFile(file) { |
| 331 | return nil, 0, fmt.Errorf("zip entry %s is not a regular file", file.Name) |
| 332 | } |
| 333 | if !hasDynamicLibraryExtension(cleanedName) { |
| 334 | continue |
| 335 | } |
| 336 | if cleanedName != targetName && cleanedName != versionedTargetName { |
| 337 | if path.Base(cleanedName) == targetName || path.Base(cleanedName) == versionedTargetName { |
| 338 | return nil, 0, fmt.Errorf("target dynamic library must be at zip root") |
| 339 | } |
| 340 | return nil, 0, fmt.Errorf("dynamic library filename must be %s or %s", targetName, versionedTargetName) |
| 341 | } |
| 342 | if target != nil { |
| 343 | return nil, 0, fmt.Errorf("zip contains multiple target dynamic libraries") |
| 344 | } |
| 345 | target = file |
| 346 | } |
| 347 | if target == nil { |
| 348 | return nil, 0, fmt.Errorf("zip does not contain %s", targetName) |
| 349 | } |
| 350 | |
| 351 | handle, errOpen := target.Open() |
| 352 | if errOpen != nil { |
| 353 | return nil, 0, fmt.Errorf("open %s: %w", targetName, errOpen) |
| 354 | } |
| 355 | defer func() { |
| 356 | if errClose := handle.Close(); errClose != nil { |
| 357 | log.WithError(errClose).Debug("failed to close plugin archive entry") |
| 358 | } |
| 359 | }() |
| 360 | data, errRead := io.ReadAll(handle) |
| 361 | if errRead != nil { |
| 362 | return nil, 0, fmt.Errorf("read %s: %w", targetName, errRead) |
| 363 | } |
| 364 | mode := target.FileInfo().Mode().Perm() |
| 365 | if mode == 0 { |
| 366 | mode = 0o755 |
| 367 | } |
| 368 | return data, mode, nil |
| 369 | } |
| 370 | |
| 371 | func versionedPluginFileName(id string, version string, goos string) string { |
| 372 | return strings.TrimSpace(id) + "-v" + normalizeVersion(version) + pluginExtension(goos) |
no test coverage detected