|
All checks were successful
CI / changes (pull_request) Successful in 7s
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 51s
sanitize_image декодировал изображение целиком (img.load) ДО ресайза, а Pillow MAX_IMAGE_PIXELS оставался дефолтным (~89 MP). Хорошо сжимаемый ≤10 MB аплоад с заявленными ~89-178 MP разворачивался в raw RGB буфер на сотни MB до thumbnail — OOM-kill backend'а (768 MiB, #2214), усиление ×12 слотов на estimate. Defense in depth: - _MAX_PIXELS = 40 MP: проверка img.size (из хедера, без декода) ДО img.load; превышение → ImageSanitizationError без загрузки полного буфера. - Image.MAX_IMAGE_PIXELS понижен до 40 MP — Pillow сам бросает DecompressionBombError на любом декод-пути в обход явной проверки. - Явный except Image.DecompressionBombError + re-raise ImageSanitizationError (byte/pixel cap) до широкого except — грациозный reject, не 500. - _MAX_BYTES backstop (endpoint уже режет 10 MB → 413, но сервис standalone). Контракт caller'а не меняется: reject → ImageSanitizationError → HTTP 400. Тест tests/services/test_image_sanitizer.py: happy-path, resize, pixel-flood без декода (load не вызывается), byte-backstop, граница cap, garbage bytes. |
||
|---|---|---|
| .. | ||
| exporters | ||
| matching | ||
| __init__.py | ||
| account_quota.py | ||
| brand.py | ||
| buildings_query.py | ||
| cache.py | ||
| cian_price_history.py | ||
| cian_session.py | ||
| dadata.py | ||
| domclick_session.py | ||
| domrf_kapremont_loader.py | ||
| estimator.py | ||
| gar_flats_loader.py | ||
| geocoder.py | ||
| house_dedup_merge.py | ||
| house_imv_backfill.py | ||
| house_metadata.py | ||
| image_sanitizer.py | ||
| location_coef.py | ||
| product_handlers.py | ||
| proxy_pool.py | ||
| rosreestr_poll.py | ||
| sber_index.py | ||
| scheduler.py | ||
| scrape_runs.py | ||
| scraper_adapters.py | ||
| scraper_settings.py | ||
| search_query.py | ||
| yandex_address_backfill.py | ||
| yandex_price_history.py | ||
| zhkh_flats_loader.py | ||