safe_image 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -12
  3. data/README.md +140 -287
  4. data/SECURITY.md +22 -11
  5. data/docs/architecture.md +63 -0
  6. data/ext/safe_image_vips_helper/extconf.rb +43 -0
  7. data/ext/safe_image_vips_helper/safe_image_vips_helper.c +1007 -0
  8. data/lib/safe_image/api/metadata.rb +85 -0
  9. data/lib/safe_image/api/transform.rb +152 -0
  10. data/lib/safe_image/backend_label.rb +24 -0
  11. data/lib/safe_image/formats.rb +96 -0
  12. data/lib/safe_image/ico.rb +42 -40
  13. data/lib/safe_image/image_magick_backend.rb +219 -162
  14. data/lib/safe_image/jpegli_backend.rb +64 -44
  15. data/lib/safe_image/metadata_operations.rb +155 -0
  16. data/lib/safe_image/native.rb +96 -290
  17. data/lib/safe_image/native_helper.rb +281 -0
  18. data/lib/safe_image/operation_backends/base.rb +83 -0
  19. data/lib/safe_image/operation_backends/image_magick.rb +123 -0
  20. data/lib/safe_image/operation_backends/vips.rb +251 -0
  21. data/lib/safe_image/operation_backends.rb +27 -0
  22. data/lib/safe_image/operation_set.rb +22 -0
  23. data/lib/safe_image/optimizer.rb +225 -98
  24. data/lib/safe_image/path_safety.rb +11 -0
  25. data/lib/safe_image/processor.rb +122 -85
  26. data/lib/safe_image/quality_defaults.rb +23 -0
  27. data/lib/safe_image/remote.rb +248 -144
  28. data/lib/safe_image/result.rb +71 -23
  29. data/lib/safe_image/runner.rb +60 -23
  30. data/lib/safe_image/sandbox.rb +44 -218
  31. data/lib/safe_image/staged_output.rb +44 -0
  32. data/lib/safe_image/svg_metadata.rb +74 -69
  33. data/lib/safe_image/transform_operations.rb +139 -0
  34. data/lib/safe_image/version.rb +1 -1
  35. data/lib/safe_image/vips_backend.rb +13 -12
  36. data/lib/safe_image.rb +62 -306
  37. metadata +43 -37
  38. data/lib/safe_image/discourse_compat.rb +0 -441
  39. data/lib/safe_image/svg_css.rb +0 -314
  40. data/lib/safe_image/svg_sanitizer.rb +0 -583
  41. data/lib/safe_image/vips_glue.rb +0 -361
  42. data/lib/safe_image/zygote.rb +0 -619
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce9a76b504fa826aef4164c5748c800a95828ef7fda6bda3a00e7e85f0134f38
4
- data.tar.gz: 61c5ebac14806e8e3445c3e7aa73bb1ab5191cc414e1af311b752ad0be492bc7
3
+ metadata.gz: 29ce0a1f4932ad1cf1dd7e47c6ae9b29009a7d2d63d54e350ec62feb1dc09e22
4
+ data.tar.gz: 2bd28448920dc859ddb8e5a0703d51163aee702807184971b8bcea594fd36fec
5
5
  SHA512:
6
- metadata.gz: 5d15f34ca4de05f1ca4618695bc3993a000ce38a7de54afde86ac87497c0288ad0ed37493ca31431669341be10991bbcdb5192796ea6bdb3af016943adfac2bc
7
- data.tar.gz: e71a59800452d4d396741e4e28134c47403490100233e803644a90a0ca967abd74fb5572a936a7af247411cb2055378982bccad89085085184aa92c66ca94d0d
6
+ metadata.gz: c756eb00ec11291985e5b9f6f573abf19399c0592e1e7d390e9239e29d359893432f55a86283441d22e22bd6a3b0d0f98b3886735d73737c809937320220b0ca
7
+ data.tar.gz: 2b7b4e9d309a6184a9881010eb058990eb4b86b293ca717c26f12d89cc9310fa8dc03a8bb9dcbeb6071840529a86f0d68726cda8715602d46ab1bc7bb80f8aae
data/CHANGELOG.md CHANGED
@@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.0 - 2026-06-22]
9
+
10
+ ### Changed
11
+
12
+ - **The `:vips` backend now runs libvips in the bundled native helper process.**
13
+ Ruby no longer loads libvips into the application process for probing,
14
+ thumbnailing, converting, orientation, dominant-color, ICO pixel extraction,
15
+ or letter-avatar generation. The helper exposes only the operations Safe Image
16
+ calls, blocks unsafe libvips operations/loaders, and fails closed when the
17
+ helper is unavailable; there is still no fallback from `:vips` to
18
+ ImageMagick.
19
+ - **Sandboxing now uses the public Landlock API around helper/tool processes.**
20
+ The previous Ruby zygote/worker sandbox plumbing was removed in favour of
21
+ simpler process execution with explicit read/write/execute allowlists and the
22
+ existing rlimits/network-deny posture.
23
+ - **Operation dispatch was simplified.** Transform and metadata operations now
24
+ dispatch directly to backend operation classes, removing an internal
25
+ forwarding layer while preserving the public API.
26
+ - **PNG optimization now mirrors Discourse's ordering.** Safe Image runs a
27
+ lossless PNG optimizer first, then optionally runs `pngquant` for small lossy
28
+ PNG optimization attempts. `oxipng` remains preferred when installed, with
29
+ `optipng` accepted as a packaged fallback.
30
+
31
+ ### Added
32
+
33
+ - Added a shared metadata result builder to keep SVG, ICO, vips, and
34
+ ImageMagick metadata probe results consistent.
35
+ - Added a `native:build` rake task and made `rake test` build/install the
36
+ `safe_image_vips_helper` binary before running the test suite.
37
+
38
+ ### Fixed
39
+
40
+ - Fixed source-tree and CI test runs where `SafeImage.configure!(backend:
41
+ :vips)` failed because `lib/safe_image/safe_image_vips_helper` had not been
42
+ built yet.
43
+ - Fixed CI setup order so libvips development headers are installed before
44
+ bundler/native build steps run.
45
+ - Fixed CI portability by avoiding an apt dependency on unavailable `oxipng`
46
+ packages; CI now uses packaged `optipng` for PNG lossless optimizer coverage.
47
+
48
+ ## [0.4.0 - 2026-06-18]
49
+
50
+ ### Removed (breaking)
51
+
52
+ - Removed `SafeImage.sanitize_svg!` and the internal SVG/CSS sanitizer
53
+ implementation. Safe Image still supports bounded SVG metadata probing for
54
+ local and remote `.svg` files, but applications that need to clean or inline
55
+ user-supplied SVG content must use a dedicated sanitizer outside this gem.
56
+ - Removed the compatibility/in-place file-writing APIs. `resize`, `crop`,
57
+ `downsize`, `convert`, `fix_orientation`, `convert_favicon_to_png`, and
58
+ `optimize` now require explicit, distinct `input:` and `output:` paths;
59
+ `optimize_image!` and `convert_to_jpeg` are gone.
60
+
8
61
  ## [0.3.0 - 2026-06-12]
9
62
 
10
63
  ### Changed (breaking)
@@ -81,8 +134,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
81
134
  allowlist, all TCP denied on ABI ≥ 4, abstract-unix-socket/signal scopes on
82
135
  ABI ≥ 6), and — when the installed `landlock` gem exposes
83
136
  `seccomp_deny_network!` — the helper's deny-all-network seccomp filter
84
- (blocking sockets of every family, closing the UDP gap the in-process
85
- Landlock policy alone leaves open), *before* touching untrusted input, and
137
+ (blocking sockets of every family), *before* touching untrusted input, and
86
138
  exits after the operation. Workers are pooled so N threads run N sandboxed
87
139
  operations at once (the single zygote would serialise them): the pool grows
88
140
  on demand to `SAFE_IMAGE_ZYGOTE_WORKERS` (default 8) and offered concurrency
@@ -284,18 +336,15 @@ between backends.
284
336
  - Graceful operation without libvips: the new `SafeImage::VipsUnavailableError`
285
337
  (a subclass of `UnsupportedFormatError`) makes `backend: :auto` route through
286
338
  ImageMagick on hosts without the library, while explicit `backend: :vips`
287
- calls fail closed. `SafeImage::VipsGlue.available?` reports the state.
339
+ calls fail closed. `SafeImage::Native.available?` reports the state.
288
340
  - `docker/run.sh`: containerised validation against Debian bookworm's packaged
289
- libvips 8.14 with no toolchain installed.
341
+ libvips 8.14 and native-helper build/install.
290
342
 
291
343
  ### Changed
292
344
 
293
- - **The compiled C extension is gone.** libvips is now bound at runtime
294
- through a minimal Fiddle binding (`SafeImage::VipsGlue`) that exposes only
295
- the operations the gem invokes. Nothing compiles at gem install time; the
296
- only gem dependencies are `fiddle` and `rexml`. Minimum libvips is 8.13
297
- (Debian bookworm's 8.14 package is tested); `SAFE_IMAGE_LIBVIPS` overrides
298
- the library name.
345
+ - **The compiled C helper owns libvips execution.** libvips is initialized in
346
+ the bundled helper process, which exposes only the operations the gem invokes.
347
+ Minimum libvips is 8.13 (Debian bookworm's 8.14 package is tested).
299
348
  - All transform defaults are now native-first: `resize`, `crop`, `downsize`,
300
349
  `convert` and `thumbnail` default to `backend: :auto` (previously
301
350
  ImageMagick for the first three and `:vips` fail-closed for `thumbnail`).
@@ -337,8 +386,8 @@ between backends.
337
386
  untrusted-operation block: JPEG XL is part of the supported input surface,
338
387
  and inputs still pass extension routing, pixel caps and (optionally) the
339
388
  Landlock sandbox.
340
- - The Fiddle binding doubles as an operation allowlist, and a leak-loop test
341
- guards GObject reference handling.
389
+ - The native helper doubles as an operation allowlist, and a leak-loop test
390
+ guards helper request handling.
342
391
 
343
392
  ## [0.1.0] - 2026-06-09
344
393