fix: address batch image ci failures

This commit is contained in:
Turtle_Li
2026-07-07 10:50:36 +08:00
parent 89edba8028
commit aff148167c
11 changed files with 63 additions and 51 deletions
+2 -2
View File
@@ -5,14 +5,14 @@ exceptions:
severity: high
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2023-30533)"
mitigation: "Load only on export; restrict export permissions and data scope"
expires_on: "2026-07-06"
expires_on: "2026-08-06"
owner: "security@your-domain"
- package: xlsx
advisory: "GHSA-5pgg-2g8v-p4x9"
severity: high
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2024-22363)"
mitigation: "Load only on export; restrict export permissions and data scope"
expires_on: "2026-07-06"
expires_on: "2026-08-06"
owner: "security@your-domain"
- package: lodash
advisory: "GHSA-r5fr-rjxr-66jc"
@@ -147,7 +147,7 @@ func (h *BatchImageHandler) ItemContent(c *gin.Context) {
batchImageError(c, err)
return
}
defer stream.Reader.Close()
defer func() { _ = stream.Reader.Close() }()
c.Header("Content-Type", stream.ContentType)
c.Header("Content-Disposition", service.BatchImageContentDispositionAttachment(stream.Filename))
@@ -181,7 +181,7 @@ func (h *BatchImageHandler) Download(c *gin.Context) {
IncludeManifest: true,
}, c.Writer)
if err != nil {
if result == nil || c.Writer.Written() == false {
if result == nil || !c.Writer.Written() {
batchImageError(c, err)
}
return
@@ -62,16 +62,6 @@ func NewBatchImageDownloadLimiter(rdb *redis.Client, cfg *config.Config) service
}
}
func newBatchImageDownloadLimiterForTest(rdb *redis.Client, maxActive int, ttl time.Duration) *batchImageDownloadLimiter {
if maxActive <= 0 {
maxActive = defaultBatchImageDownloadConcurrency
}
if ttl <= 0 {
ttl = defaultBatchImageDownloadActiveTTL
}
return &batchImageDownloadLimiter{rdb: rdb, activePrefix: defaultBatchImageDownloadActivePrefix, maxActive: maxActive, ttl: ttl}
}
func (l *batchImageDownloadLimiter) Acquire(ctx context.Context, userID string, kind string) (service.BatchImageDownloadPermit, error) {
if l == nil || l.rdb == nil {
return nil, service.ErrBatchImageDownloadLimited
@@ -18,7 +18,12 @@ func TestBatchImageDownloadLimiter_AcquireDenyReleaseAndTTL(t *testing.T) {
mr := miniredis.RunT(t)
rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()})
t.Cleanup(func() { _ = rdb.Close() })
limiter := newBatchImageDownloadLimiterForTest(rdb, 1, time.Minute)
limiter := &batchImageDownloadLimiter{
rdb: rdb,
activePrefix: defaultBatchImageDownloadActivePrefix,
maxActive: 1,
ttl: time.Minute,
}
permit, err := limiter.Acquire(ctx, "11", "zip")
require.NoError(t, err)
@@ -25,10 +25,6 @@ func NewBatchImageRepository(db *sql.DB) service.BatchImageRepository {
return &batchImageRepository{db: db, sql: db}
}
func newBatchImageRepositoryWithSQL(sqlq batchImageSQLExecutor) *batchImageRepository {
return &batchImageRepository{sql: sqlq}
}
func (r *batchImageRepository) CreateBatchImageJob(ctx context.Context, params service.CreateBatchImageJobParams) (*service.BatchImageJob, error) {
if !service.IsSupportedBatchImageProvider(params.Provider) {
return nil, service.ErrBatchImageInvalidProvider
@@ -125,7 +121,7 @@ func (r *batchImageRepository) ListBatchImageJobsForOwner(ctx context.Context, u
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
return scanBatchImageJobs(rows)
}
@@ -449,7 +445,7 @@ func (r *batchImageRepository) batchImageItemPromptPreviews(ctx context.Context,
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
out := make(map[string]string)
for rows.Next() {
var customID string
@@ -486,7 +482,7 @@ func (r *batchImageRepository) ListBatchImageItems(ctx context.Context, batchID
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
var items []*service.BatchImageItem
for rows.Next() {
@@ -540,7 +536,7 @@ func (r *batchImageRepository) ListBatchImageJobsDueForInputCleanup(ctx context.
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
return scanBatchImageJobs(rows)
}
@@ -559,7 +555,7 @@ func (r *batchImageRepository) ListBatchImageJobsDueForOutputCleanup(ctx context
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
return scanBatchImageJobs(rows)
}
@@ -577,7 +573,7 @@ func (r *batchImageRepository) ListStaleUnsubmittedBatchImageJobs(ctx context.Co
if err != nil {
return nil, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
return scanBatchImageJobs(rows)
}
@@ -4,7 +4,11 @@ package repository
import (
"context"
"crypto/sha1"
"encoding/hex"
"errors"
"regexp"
"strings"
"testing"
"time"
@@ -12,6 +16,10 @@ import (
"github.com/stretchr/testify/require"
)
func newBatchImageRepositoryWithSQL(sqlq batchImageSQLExecutor) *batchImageRepository {
return &batchImageRepository{sql: sqlq}
}
func TestBatchImageRepository_CreateJobAndDuplicates(t *testing.T) {
ctx := context.Background()
tx := testTx(t)
@@ -325,7 +333,26 @@ func TestBatchImageRepository_AppendEvent(t *testing.T) {
func batchImageTestID(t *testing.T, prefix string) string {
t.Helper()
return "imgbatch_" + uniqueTestValue(t, prefix)
safePrefix := batchImageSafeTestIDSegment(prefix, 20)
sum := sha1.Sum([]byte(t.Name()))
return "imgbatch_" + safePrefix + "_" + hex.EncodeToString(sum[:])[:16]
}
func batchImageSafeTestIDSegment(v string, maxLen int) string {
v = strings.ToLower(strings.TrimSpace(v))
v = regexp.MustCompile(`[^a-z0-9_-]+`).ReplaceAllString(v, "-")
v = strings.Trim(v, "-_")
if v == "" {
v = "job"
}
if len(v) > maxLen {
v = v[:maxLen]
v = strings.Trim(v, "-_")
}
if v == "" {
return "job"
}
return v
}
func batchImageTestStringPtr(v string) *string {
@@ -144,7 +144,7 @@ func (s *BatchImageDownloadService) OpenItemContent(ctx context.Context, owner B
if err != nil {
return nil, ErrBatchImageResultMissing.WithCause(err)
}
defer r.Close()
defer func() { _ = r.Close() }()
line, err := findBatchImageLineImages(r, item.CustomID)
if err != nil {
@@ -207,7 +207,7 @@ func (s *BatchImageDownloadService) StreamZip(ctx context.Context, owner BatchIm
return nil, err
}
if permit != nil {
defer permit.Release(ctx)
defer func() { _ = permit.Release(ctx) }()
}
provider, account, err := s.providerAndAccount(ctx, job)
@@ -218,7 +218,7 @@ func (s *BatchImageDownloadService) StreamZip(ctx context.Context, owner BatchIm
if err != nil {
return nil, ErrBatchImageResultMissing.WithCause(err)
}
defer r.Close()
defer func() { _ = r.Close() }()
streamCtx := ctx
cancel := func() {}
@@ -546,13 +546,13 @@ func sanitizeBatchImageFilenameBase(value string) string {
for _, r := range value {
switch {
case r == '/' || r == '\\' || r == ':' || r == 0:
b.WriteByte('_')
_ = b.WriteByte('_')
case unicode.IsControl(r):
b.WriteByte('_')
_ = b.WriteByte('_')
case unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' || r == '-' || r == '.':
b.WriteRune(r)
_, _ = b.WriteRune(r)
default:
b.WriteByte('_')
_ = b.WriteByte('_')
}
}
out := strings.Trim(b.String(), ". ")
@@ -577,7 +577,7 @@ func sanitizeBatchImageFilenameExtension(extension string) string {
var b strings.Builder
for _, r := range extension {
if unicode.IsLetter(r) || unicode.IsDigit(r) {
b.WriteRune(r)
_, _ = b.WriteRune(r)
}
}
out := b.String()
@@ -285,7 +285,7 @@ func (i *BatchImageResultIndexer) Index(ctx context.Context, job *BatchImageJob,
if err != nil {
return nil, ErrBatchImageIndexOutputMissing.WithCause(err)
}
defer r.Close()
defer func() { _ = r.Close() }()
scanner := bufio.NewScanner(r)
scanner.Buffer(make([]byte, 0, 64*1024), 16*1024*1024)
@@ -577,7 +577,7 @@ func (c *GeminiBatchHTTPClient) DownloadFile(ctx context.Context, apiKey string,
return nil, "", err
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
return nil, "", readGeminiAPIError(resp)
}
contentType := resp.Header.Get("Content-Type")
@@ -612,7 +612,7 @@ func (c *GeminiBatchHTTPClient) doNoBody(req *http.Request) error {
if err != nil {
return err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return readGeminiAPIError(resp)
}
@@ -624,7 +624,7 @@ func (c *GeminiBatchHTTPClient) doJSON(req *http.Request, out any) error {
if err != nil {
return err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return readGeminiAPIError(resp)
}
@@ -450,11 +450,11 @@ func sanitizeVertexGCSPathSegment(v string) string {
for _, r := range v {
switch {
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9':
b.WriteRune(r)
_, _ = b.WriteRune(r)
case r == '-', r == '_', r == '.':
b.WriteRune(r)
_, _ = b.WriteRune(r)
default:
b.WriteByte('-')
_ = b.WriteByte('-')
}
}
return b.String()
@@ -876,7 +876,7 @@ func (s *VertexGCSObjectStore) OpenObject(ctx context.Context, accessToken strin
return nil, "", err
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
return nil, "", readVertexAPIError(resp)
}
contentType := resp.Header.Get("Content-Type")
@@ -955,7 +955,7 @@ func doVertexDecodeJSON(client *http.Client, req *http.Request, out any) error {
if err != nil {
return err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return readVertexAPIError(resp)
}
@@ -967,7 +967,7 @@ func doVertexNoBody(client *http.Client, req *http.Request) error {
if err != nil {
return err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return readVertexAPIError(resp)
}
@@ -310,13 +310,7 @@ func (s *BatchImagePublicService) Submit(ctx context.Context, owner BatchImageOw
for _, item := range normalized.Items {
refs := make([]BatchImageReference, 0, len(item.ReferenceImages))
for _, ref := range item.ReferenceImages {
refs = append(refs, BatchImageReference{
ID: ref.ID,
Type: ref.Type,
MimeType: ref.MimeType,
Data: ref.Data,
FileURI: ref.FileURI,
})
refs = append(refs, BatchImageReference(ref))
}
input.Items = append(input.Items, BatchImageInputItem{
CustomID: item.CustomID,