From dd136858f1ea40ad3c94191d647487fa4f31926c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 18 Oct 2024 20:33:49 +0200 Subject: Adding upstream version 9.0.0. Signed-off-by: Daniel Baumann --- modules/packages/goproxy/metadata.go | 94 ++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 modules/packages/goproxy/metadata.go (limited to 'modules/packages/goproxy/metadata.go') diff --git a/modules/packages/goproxy/metadata.go b/modules/packages/goproxy/metadata.go new file mode 100644 index 0000000..40f7d20 --- /dev/null +++ b/modules/packages/goproxy/metadata.go @@ -0,0 +1,94 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package goproxy + +import ( + "archive/zip" + "fmt" + "io" + "path" + "strings" + + "code.gitea.io/gitea/modules/util" +) + +const ( + PropertyGoMod = "go.mod" + + maxGoModFileSize = 16 * 1024 * 1024 // https://go.dev/ref/mod#zip-path-size-constraints +) + +var ( + ErrInvalidStructure = util.NewInvalidArgumentErrorf("package has invalid structure") + ErrGoModFileTooLarge = util.NewInvalidArgumentErrorf("go.mod file is too large") +) + +type Package struct { + Name string + Version string + GoMod string +} + +// ParsePackage parses the Go package file +// https://go.dev/ref/mod#zip-files +func ParsePackage(r io.ReaderAt, size int64) (*Package, error) { + archive, err := zip.NewReader(r, size) + if err != nil { + return nil, err + } + + var p *Package + + for _, file := range archive.File { + nameAndVersion := path.Dir(file.Name) + + parts := strings.SplitN(nameAndVersion, "@", 2) + if len(parts) != 2 { + continue + } + + versionParts := strings.SplitN(parts[1], "/", 2) + + if p == nil { + p = &Package{ + Name: strings.TrimSuffix(nameAndVersion, "@"+parts[1]), + Version: versionParts[0], + } + } + + if len(versionParts) > 1 { + // files are expected in the "root" folder + continue + } + + if path.Base(file.Name) == "go.mod" { + if file.UncompressedSize64 > maxGoModFileSize { + return nil, ErrGoModFileTooLarge + } + + f, err := archive.Open(file.Name) + if err != nil { + return nil, err + } + defer f.Close() + + bytes, err := io.ReadAll(&io.LimitedReader{R: f, N: maxGoModFileSize}) + if err != nil { + return nil, err + } + + p.GoMod = string(bytes) + + return p, nil + } + } + + if p == nil { + return nil, ErrInvalidStructure + } + + p.GoMod = fmt.Sprintf("module %s", p.Name) + + return p, nil +} -- cgit v1.2.3