From 614a1d51b0740955a4ef07c385e88962b4870642 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 28 Jul 2026 10:46:54 -0400 Subject: [PATCH] Disable libvips unfuzzed operations and add test coverage for (un)supported file types. BMP, ICO, and PSD attachments are no longer variable, and the picture views call `variant(:large)` unconditionally, which raises `ActiveStorage::InvariableError`. `Picture#large_image` will fall back to the original attachment. --- app/models/picture.rb | 4 + app/views/leafables/show.html.erb | 2 +- app/views/leaves/_edit.html.erb | 2 +- app/views/leaves/_leaf.html.erb | 2 +- app/views/pictures/_form.html.erb | 2 +- config/initializers/vips.rb | 8 ++ test/controllers/leafables_controller_test.rb | 10 ++ test/fixtures/files/pixel.bmp | Bin 0 -> 58 bytes test/lib/vips_loader_policy_test.rb | 118 ++++++++++++++++++ test/models/picture_test.rb | 11 ++ 10 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 config/initializers/vips.rb create mode 100644 test/fixtures/files/pixel.bmp create mode 100644 test/lib/vips_loader_policy_test.rb diff --git a/app/models/picture.rb b/app/models/picture.rb index bb98a115..6573a97b 100644 --- a/app/models/picture.rb +++ b/app/models/picture.rb @@ -5,6 +5,10 @@ class Picture < ApplicationRecord attachable.variant :large, resize_to_limit: [ 1500, 1500 ] end + def large_image + image.variable? ? image.variant(:large) : image + end + def markable caption end diff --git a/app/views/leafables/show.html.erb b/app/views/leafables/show.html.erb index 99d0af3c..bc64e1bc 100644 --- a/app/views/leafables/show.html.erb +++ b/app/views/leafables/show.html.erb @@ -27,7 +27,7 @@ action: "lightbox#open:prevent", lightbox_target: "image", lightbox_url_value: rails_blob_path(@leaf.picture.image, disposition: "attachment", only_path: true) } do %> - <%= image_tag @leaf.picture.image.variant(:large), loading: "lazy" %> + <%= image_tag @leaf.picture.large_image, loading: "lazy" %> <% end %> <% else %> <%= image_tag "default-picture.webp", alt: "No image uploaded", loading: "lazy" %> diff --git a/app/views/leaves/_edit.html.erb b/app/views/leaves/_edit.html.erb index 43633f58..559939d5 100644 --- a/app/views/leaves/_edit.html.erb +++ b/app/views/leaves/_edit.html.erb @@ -7,7 +7,7 @@ <%= link_to leafable_path(leaf), class: "toc__thumbnail", data: { turbo_frame: "_top" } do %> <%= leaf.section.body if leaf.section? %> <%= sanitize_content(leaf.leafable.body.to_html) if leaf.page? %> - <%= image_tag leaf.leafable.image.variant(:large) if leaf.picture&.image&.attached? %> + <%= image_tag leaf.leafable.large_image if leaf.picture&.image&.attached? %> <% end %>
diff --git a/app/views/leaves/_leaf.html.erb b/app/views/leaves/_leaf.html.erb index dccdd672..e6282542 100644 --- a/app/views/leaves/_leaf.html.erb +++ b/app/views/leaves/_leaf.html.erb @@ -27,7 +27,7 @@ <%= sanitize_content leaf.page.html_preview if leaf.page? %> <% if leaf.picture? %> - <%= image_tag leaf.leafable.image.attached? ? leaf.leafable.image.variant(:large) : "default-picture.webp" %> + <%= image_tag leaf.leafable.image.attached? ? leaf.leafable.large_image : "default-picture.webp" %> <% end %>
diff --git a/app/views/pictures/_form.html.erb b/app/views/pictures/_form.html.erb index da1b4948..1805eb72 100644 --- a/app/views/pictures/_form.html.erb +++ b/app/views/pictures/_form.html.erb @@ -1,6 +1,6 @@ <%= leafable_edit_form(picture, id: "leafable-editor") do |form| %>