func()

in command-runner/internal/containers/docker/docker_run.go [448:495]


func (cr *dockerContainer) copyOut(hostPath string, containerPath string) common.Executor {
	return func(ctx context.Context) error {
		log.Ctx(ctx).Printf("Extracting content from '%s' to '%s'", containerPath, hostPath)
		if out, _, err := cr.cli.CopyFromContainer(ctx, cr.id, containerPath); err != nil {
			return fmt.Errorf("failed to copy content from container: %w", err)
		} else {
			tr := tar.NewReader(out)
			defer out.Close()
			for {
				hdr, err := tr.Next()
				if err == io.EOF {
					break
				}
				if err != nil {
					return fmt.Errorf("error processing archive: %w", err)
				}
				hostPath := filepath.Join(hostPath, hdr.Name) // #nosec G305 - mitigated by following check
				if !strings.HasPrefix(hostPath, filepath.Clean(hostPath)) {
					return fmt.Errorf("content path is tainted: %s", hostPath)
				}
				switch hdr.Typeflag {
				case tar.TypeDir:
					if err := os.MkdirAll(hostPath, 0755); err != nil {
						return err
					}
				case tar.TypeReg:
					if err := os.MkdirAll(filepath.Dir(hostPath), 0755); err != nil {
						return err
					}
					if f, err := os.Create(hostPath); err != nil {
						return err
					} else {
						for {
							_, err := io.CopyN(f, tr, 1024)
							if err != nil {
								if err == io.EOF {
									break
								}
								return fmt.Errorf("unable to copy tr file to output: %w", err)
							}
						}
					}
				}
			}
		}
		return nil
	}
}