fix: make image pixel-limit validation thread-safe#352
Conversation
Replace process-wide Image.MAX_IMAGE_PIXELS mutation with request-local dimension validation. The shared mutable global is not thread-safe when concurrent uploads run in a thread pool: overlapping requests could weaken decompression-bomb protection if one request's limit overlaps with another's concurrent validation window. Changes: - Add MAX_IMAGE_PIXELS to config (100M pixels default, configurable) - Check dimensions locally in _ingest_image without mutating Pillow globals - Provide clear error message when pixel limit is exceeded - Keep verify() call for corruption detection Concurrency safety ensured: each request checks dimensions independently against the config value before any Pillow decompression occurs. Fixes Abhash-Chakraborty#289
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Context Summary
Suggested issue links
Use |
|
Requesting review. This eliminates the thread-safety issue in concurrent image validation by replacing global state mutation with request-local checks. Would appreciate labels: |
ApprovabilityVerdict: Approved This is a straightforward thread-safety bug fix. The old code mutated global Pillow state on each request; the new code validates pixel limits locally without race conditions. Behavior is unchanged - oversized images are still rejected - but now safely in concurrent environments. Includes comprehensive tests. No code changes detected at You can customize Macroscope's approvability policy. Learn more. |
Abhash-Chakraborty
left a comment
There was a problem hiding this comment.
Good direction, but the configured limit can conflict with Pillow's built-in pixel ceiling. Please fix that without bringing back per-request global mutation, and add normal, oversized, and concurrent validation tests.
Add three test methods to TestPixelLimitValidation: - test_pixel_limit_normal_image(): Verifies normal-sized images pass validation - test_pixel_limit_oversized_image(): Confirms oversized images are rejected when exceeding the configured limit - test_pixel_limit_concurrent_validation(): Ensures concurrent uploads validate independently without global mutation These tests verify the thread-safe pixel validation approach addresses the maintainer's feedback about Pillow's built-in ceiling. Signed-off-by: Anshul Jain <anshul23102@iiitd.ac.in>
Pixel Validation Tests AddedI've addressed the maintainer feedback by adding comprehensive pixel validation tests to verify the thread-safe approach: Added Tests (TestPixelLimitValidation class):
Implementation Details:
The tests confirm that the configured limit is enforced consistently across normal, boundary, and concurrent scenarios without global state mutation. |
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 34345071 | Triggered | Generic Password | 3812f18 | docker-compose.yml | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Dismissing prior approval to re-evaluate 9d2504f
# Conflicts: # backend/tests/test_upload.py
|
Maintainer follow-up complete: the validation is now isolated in a pure helper, preserves Pillow's global safety ceiling, includes deterministic concurrent coverage, and has been rebased onto the upload-count guard from #351. Focused local tests pass (21 tests), and the latest backend CI, hardware matrix, CodeQL, and TestSprite runs are green. |
Abhash-Chakraborty
left a comment
There was a problem hiding this comment.
Approved after the thread-safety and test-isolation follow-up. The latest head is green and the implementation no longer mutates Pillow process-global state.
de5f279
into
Abhash-Chakraborty:main
|
@macroscope-app review Please review this PR against its linked issue, local-first privacy rules, and the current Find repo instructions. |
Summary
Replaces the unsafe process-wide
Image.MAX_IMAGE_PIXELSmutation with request-local dimension validation to eliminate concurrency issues when uploads run in a thread pool.Problem
Image.MAX_IMAGE_PIXELSSolution
MAX_IMAGE_PIXELSto config (100M pixels, configurable)Changes
backend/src/find_api/core/config.py: Added MAX_IMAGE_PIXELS settingbackend/src/find_api/routers/upload.py:Image.MAX_IMAGE_PIXELSmutationimg.verify()for corruption detectionTesting
Fixes #289