← Back to PRs

#19161: feat: Add Pillow fallback for image processing when Sharp fails

by Detrol open 2026-02-17 13:22 View on GitHub →
size: M
## Summary Sharp requires CPU v2 microarchitecture which is not available on older systems. This PR adds a Python/Pillow fallback that activates when Sharp fails. ## Changes - Added `isPillowAvailable()` to detect Python Pillow installation - Added `pillowResizeToJpeg()` for image processing via Python - Modified `resizeToJpeg()` to try Sharp first, fallback to Pillow on error - Proper error handling with cause preservation ## Motivation - Users on older hardware or restricted environments where native Sharp binaries are incompatible - Transparent fallback that maintains the same API - Tested on Ubuntu 22.04 with Python Pillow 9.0.1 ## Testing - [x] Local testing with Pillow installed - [x] `pnpm check` passes (format, typecheck, lint) - [x] `pnpm build` succeeds - [x] Image processing works with xAI/Grok vision model ## Related This enables image processing on systems where Sharp fails due to CPU incompatibility. --- **Note:** This PR is AI-assisted (built with guidance from OpenClaw documentation and iterative debugging). <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR adds a Python/Pillow fallback for image resizing when Sharp native binaries fail (e.g., on older CPUs lacking v2 microarchitecture). It also updates `appcast.xml` with the v2026.2.15 release entry. - **Path injection vulnerability**: File paths are interpolated directly into a Python script string via template literals. If `os.tmpdir()` returns a path with single quotes, this breaks the Python string boundary and could allow code execution. Should use `sys.argv` to pass paths instead. - **Missing EXIF orientation handling**: The Pillow fallback does not apply EXIF orientation correction (Sharp's `.rotate()`), so mobile photos may appear rotated/flipped. - **Temp file race condition**: Uses `Date.now()` for temp filenames instead of the existing `withTempDir` pattern (which uses `fs.mkdtemp` for unique directories), risking collisions under concurrent processing. - **Overly broad fallback trigger**: The catch block around Sharp catches all errors (including legitimate image failures), not just Sharp unavailability, causing unnecessary fallthrough to Pillow. <h3>Confidence Score: 2/5</h3> - This PR has a code injection vulnerability and functional gaps that should be addressed before merging. - Score of 2 reflects the path injection risk in the Python script string interpolation and the missing EXIF orientation handling which will cause incorrect image output for a common class of inputs (mobile photos). The race condition in temp file naming and the overly broad error catch are additional concerns. The concept is sound, but the implementation needs hardening. - `src/media/image-ops.ts` needs attention — specifically the `pillowResizeToJpeg` function (path injection, missing EXIF handling, temp file race) and the `resizeToJpeg` catch block (overly broad fallback trigger). <sub>Last reviewed commit: babc016</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs