mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
Bound the memory used when parsing uploaded packages, so instances with low memory limits survive non-standard packages. 1. Metadata files are read through a size-limited reader, archives themselves stay unbounded so large payloads keep working 2. zstd decoding caps the window at 128 MiB, the zstd CLI default 3. RPM headers go through a first-party reader with rpmlib's size and array count limits that allocates only what the upload contains, until https://github.com/sassoftware/go-rpmutils/pull/44 is released. Signing still verifies the payload digest, and its signature header matches rpmsign's byte for byte 4. Swift and NuGet read the zip entry they size-checked, a duplicate name could stand in for it before 5. Terraform states check `LIMIT_SIZE_TERRAFORM_STATE` before parsing, NuGet symbol PDBs share a 256 MiB budget 6. Oversized container configs are rejected instead of stored without metadata, invalid Vagrant boxes answer 400 instead of 500 Signed-off-by: techknowlogick <git@tklk.dev> Co-authored-by: techknowlogick <git@tklk.dev> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: techknowlogick <techknowlogick@gitea.com>
105 lines
2.7 KiB
Go
105 lines
2.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package terraform
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"time"
|
|
|
|
"gitea.dev/models/db"
|
|
packages_model "gitea.dev/models/packages"
|
|
"gitea.dev/modules/json"
|
|
"gitea.dev/modules/packages"
|
|
"gitea.dev/modules/util"
|
|
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
const (
|
|
LockFile = "terraform.lock"
|
|
|
|
maxLockInfoSize = 64 * 1024
|
|
)
|
|
|
|
// LockInfo is the metadata for a terraform lock.
|
|
type LockInfo struct {
|
|
ID string `json:"ID"`
|
|
Operation string `json:"Operation"`
|
|
Info string `json:"Info"`
|
|
Who string `json:"Who"`
|
|
Version string `json:"Version"`
|
|
Created time.Time `json:"Created"`
|
|
Path string `json:"Path"`
|
|
}
|
|
|
|
func (l *LockInfo) IsLocked() bool {
|
|
return l.ID != ""
|
|
}
|
|
|
|
func ParseLockInfo(r io.Reader) (*LockInfo, error) {
|
|
var lock LockInfo
|
|
err := json.NewDecoder(packages.NewLimitedReader(r, maxLockInfoSize)).Decode(&lock)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// ID is required. Rest is less important.
|
|
if lock.ID == "" {
|
|
return nil, util.NewInvalidArgumentErrorf("terraform lock is missing an ID")
|
|
}
|
|
return &lock, nil
|
|
}
|
|
|
|
// GetLock returns the terraform lock for the given package.
|
|
// Lock is empty if no lock exists.
|
|
func GetLock(ctx context.Context, packageID int64) (LockInfo, error) {
|
|
var lock LockInfo
|
|
locks, err := packages_model.GetPropertiesByName(ctx, packages_model.PropertyTypePackage, packageID, LockFile)
|
|
if err != nil {
|
|
return lock, err
|
|
}
|
|
if len(locks) == 0 || locks[0].Value == "" {
|
|
return lock, nil
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(locks[0].Value), &lock)
|
|
return lock, err
|
|
}
|
|
|
|
// SetLock sets the terraform lock for the given package.
|
|
func SetLock(ctx context.Context, packageID int64, lock *LockInfo) error {
|
|
jsonBytes, err := json.Marshal(lock)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return updateLock(ctx, packageID, string(jsonBytes), builder.Eq{"value": ""})
|
|
}
|
|
|
|
// RemoveLock removes the terraform lock for the given package.
|
|
func RemoveLock(ctx context.Context, packageID int64) error {
|
|
return updateLock(ctx, packageID, "", builder.Neq{"value": ""})
|
|
}
|
|
|
|
func updateLock(ctx context.Context, refID int64, value string, cond builder.Cond) error {
|
|
pp, ok, err := db.Get[packages_model.PackageProperty](ctx, builder.Eq{"ref_type": packages_model.PropertyTypePackage, "ref_id": refID, "`name`": LockFile})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if ok {
|
|
n, err := db.GetEngine(ctx).ID(pp.ID).And(cond).Cols("value").Update(&packages_model.PackageProperty{Value: value})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if n == 0 {
|
|
return errors.New("failed to update lock state")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
_, err = packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, refID, LockFile, value)
|
|
return err
|
|
}
|