Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ should not be compared across sources. Face detection does not perform identity
recognition. Blurred, obscured, or highly stylized faces may use the saliency
fallback.

Requests are limited to 10 MiB and decoded images to 20 megapixels. Separate
Requests are limited to 32 MiB and decoded images to 40 megapixels. Separate
upload and analysis admission limits bound buffered-body and decoded-image
memory without allowing slow uploads to reserve inference capacity. Both models
are loaded once at startup and their inference sessions are reused safely
Expand Down
4 changes: 2 additions & 2 deletions cmd/autogravity/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
)

const (
maxRequestBytes = 10 << 20 // 10 MiB, including multipart overhead.
maxRequestBytes = 32 << 20 // 32 MiB, including multipart overhead.
maxConcurrentUploads = 4 // Bounds buffered bodies without reserving inference.
defaultIntraOpThreads = 1 // Avoid N requests multiplying ONNX worker threads.
defaultFaceModelPath = "models/face_detection_yunet_2023mar.onnx"
Expand Down Expand Up @@ -290,7 +290,7 @@ func (app *application) handleAnalyze(w http.ResponseWriter, r *http.Request) {
outcome = "invalid_request"
var tooLarge *http.MaxBytesError
if errors.As(err, &tooLarge) {
writeError(w, http.StatusRequestEntityTooLarge, "image exceeds the 10 MiB request limit")
writeError(w, http.StatusRequestEntityTooLarge, fmt.Sprintf("image exceeds the %d MiB request limit", maxRequestBytes>>20))
return
}
writeError(w, http.StatusBadRequest, err.Error())
Expand Down
17 changes: 17 additions & 0 deletions cmd/autogravity/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"time"

"autogravity/internal/facedetection"
"autogravity/internal/imageutil"
"autogravity/internal/saliency"
)

Expand Down Expand Up @@ -302,6 +303,7 @@ func TestHandleAnalyzeErrors(t *testing.T) {
{name: "unsupported format", method: http.MethodPost, contentType: "application/octet-stream", body: []byte("not an image"), wantStatus: http.StatusUnsupportedMediaType},
{name: "empty body", method: http.MethodPost, contentType: "image/png", wantStatus: http.StatusBadRequest},
{name: "request too large", method: http.MethodPost, contentType: "image/png", body: make([]byte, maxRequestBytes+1), wantStatus: http.StatusRequestEntityTooLarge},
{name: "11 MiB body is within limit", method: http.MethodPost, contentType: "image/png", body: make([]byte, 11<<20), wantStatus: http.StatusUnsupportedMediaType},
}

for _, tt := range tests {
Expand All @@ -319,6 +321,21 @@ func TestHandleAnalyzeErrors(t *testing.T) {
}
}

func TestProductionPhotographFitsLimits(t *testing.T) {
const (
productionPNGBytes = 28_026_017
productionWidth = 6000
productionHeight = 4000
)
if maxRequestBytes < productionPNGBytes {
t.Fatalf("maxRequestBytes = %d, production photograph is %d bytes", maxRequestBytes, productionPNGBytes)
}
pixels := int64(productionWidth) * int64(productionHeight)
if pixels > imageutil.MaxPixels {
t.Fatalf("MaxPixels = %d, production photograph is %d pixels", imageutil.MaxPixels, pixels)
}
}
Comment on lines +324 to +337

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Implementation-Coupled Regression Tests

TestProductionPhotographFitsLimits only compares duplicated dimensions and byte counts with maxRequestBytes and imageutil.MaxPixels. The related header-only test also requires decoding to fail, and the existing valid fixtures are all small. As a result, these tests can remain green even if a valid 6000×4000 image cannot be decoded or accepted by the handler. This violates the repository directive to test observable behavior rather than mirror source configuration. Replace these checks with a valid generated or fixture image that exercises successful decoding or handler acceptance; this repository requirement must be satisfied before merging.

Context Used: Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. (source)

Knowledge Base Used: CLI integration and evaluation

Prompt To Fix With AI
This is a comment left during a code review.
Path: cmd/autogravity/main_test.go
Line: 324-337

Comment:
**Implementation-Coupled Regression Tests**

`TestProductionPhotographFitsLimits` only compares duplicated dimensions and byte counts with `maxRequestBytes` and `imageutil.MaxPixels`. The related header-only test also requires decoding to fail, and the existing valid fixtures are all small. As a result, these tests can remain green even if a valid 6000×4000 image cannot be decoded or accepted by the handler. This violates the repository directive to test observable behavior rather than mirror source configuration. Replace these checks with a valid generated or fixture image that exercises successful decoding or handler acceptance; this repository requirement must be satisfied before merging.

**Context Used:** Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))

**Knowledge Base Used:** [CLI integration and evaluation](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/appwrite/autogravity/-/docs/cli-validation.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex


func TestHandleAnalyzeBoundsConcurrentWork(t *testing.T) {
analyzer := &fakeAnalyzer{delay: 10 * time.Millisecond}
const concurrency = 2
Expand Down
2 changes: 1 addition & 1 deletion docs/src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ function DocsPage() {
<section id="limits" className="doc-section">
<SectionTitle kicker="Reference" title="Limits" />
<p className="doc-copy">
Requests are limited to 10 MiB and decoded images to 20 megapixels.
Requests are limited to 32 MiB and decoded images to 40 megapixels.
Separate upload and analysis admission limits bound buffered-body and
decoded-image memory without allowing slow uploads to reserve
inference capacity. Both models are loaded once at startup and their
Expand Down
5 changes: 4 additions & 1 deletion internal/imageutil/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import (
_ "golang.org/x/image/webp"
)

const MaxPixels = 20_000_000
// MaxPixels is the decoded width*height ceiling. 40 megapixels covers common
// 24 MP camera photographs (for example 6000x4000) while still rejecting
// decompression bombs before pixels are allocated.
const MaxPixels = 40_000_000

var (
ErrUnsupportedFormat = errors.New("unsupported image format")
Expand Down
12 changes: 11 additions & 1 deletion internal/imageutil/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,22 @@ func TestDecodeRejectsUnknownFormat(t *testing.T) {
}

func TestDecodeRejectsExcessivePixelCount(t *testing.T) {
_, err := Decode(oversizedPNGHeader(5_000, 5_000))
_, err := Decode(oversizedPNGHeader(8_000, 8_000))
if !errors.Is(err, ErrImageTooLarge) {
t.Fatalf("Decode() error = %v, want ErrImageTooLarge", err)
}
}

func TestDecodeAccepts24MegapixelCameraPhoto(t *testing.T) {
_, err := Decode(oversizedPNGHeader(6000, 4000))
if errors.Is(err, ErrImageTooLarge) {
t.Fatal("rejected 6000x4000 photograph that production must accept")
}
if err == nil {
t.Fatal("header-only fixture unexpectedly decoded")
}
}

func TestPrepareProducesNormalizedNCHW(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, 1, 1))
img.SetRGBA(0, 0, color.RGBA{R: 255, G: 128, B: 0, A: 255})
Expand Down