From 83a83407086cce2b6ccca7930195c30751ced4e1 Mon Sep 17 00:00:00 2001 From: Andrey Glushkov Date: Wed, 20 Dec 2023 16:59:03 +0300 Subject: [PATCH] Add wrappers for vips_block_untrusted_set and vips_operation_block_set methods ```ruby Vips.block("VipsForeignLoad", true); Vips.block("VipsForeignLoadJpeg", false) Vips.block_untrusted(true) ``` Use `vips -l` at the command-line to see the operations classes hierarchy. --- CHANGELOG.md | 2 ++ lib/vips.rb | 25 +++++++++++++++++++++++++ spec/block_operations_spec.rb | 34 ++++++++++++++++++++++++++++++++++ spec/image_spec.rb | 4 ---- spec/spec_helper.rb | 8 ++++++++ 5 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 spec/block_operations_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 8848ddb..77c9d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master +* add `Vips.block_untrusted` method to block all untrusted operations. Only for libvips >= 8.13. [Docs](https://www.libvips.org/API/current/libvips-vips.html#vips-block-untrusted-set). [#382](https://github.com/libvips/ruby-vips/pull/382) [aglushkov](https://github.com/aglushkov) +* add `Vips.block` method to block specific operation. Only for libvips >= 8.13. [Docs](https://www.libvips.org/API/current/VipsOperation.html#vips-operation-block-set). [#382](https://github.com/libvips/ruby-vips/pull/382) [aglushkov](https://github.com/aglushkov) * `new_from_source` keeps a ref to the source object [taylorthurlow] * some fixes to object references system diff --git a/lib/vips.rb b/lib/vips.rb index 5c10d49..f0e7461 100644 --- a/lib/vips.rb +++ b/lib/vips.rb @@ -779,6 +779,31 @@ def self.at_least_libvips?(x, y) major > x || (major == x && minor >= y) end + if at_least_libvips?(8, 13) + attach_function :vips_block_untrusted_set, [:bool], :void + attach_function :vips_operation_block_set, %i[string bool], :void + + # Block/unblock all untrusted operations from running. + # Use `vips -l` at the command-line to see the class hierarchy and which operations are marked as untrusted. + def self.block_untrusted(enabled) + vips_block_untrusted_set(enabled) + end + + # Block/unblock all operations in the libvips class hierarchy at specified *operation_name* and below. + # + # For example this will block all loaders except JPEG + # + # Vips.block("VipsForeignLoad", true); + # Vips.block("VipsForeignLoadJpeg", false) + # + # Use `vips -l` at the command-line to see the class hierarchy. + # This call does nothing if the named operation is not found. + # + def self.block(operation_name, enabled) + vips_operation_block_set(operation_name, enabled) + end + end + # Get a list of all supported file suffixes. # # @return [[String]] array of supported suffixes diff --git a/spec/block_operations_spec.rb b/spec/block_operations_spec.rb new file mode 100644 index 0000000..6cd0e7c --- /dev/null +++ b/spec/block_operations_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" + +RSpec.describe Vips, version: [8, 13] do + let(:svg_image) { simg("lion.svg") } + let(:jpg_image) { simg("wagon.jpg") } + + if has_svg? + it "can block untrusted operations" do + untrusted_image = svg_image # svgload operation is known as untrusted + + # Block + Vips.block_untrusted(true) + expect { Vips::Image.new_from_file(untrusted_image) }.to raise_error Vips::Error, /svgload/ + + # Unblock + Vips.block_untrusted(false) + expect { Vips::Image.new_from_file(untrusted_image) }.not_to raise_error + end + end + + if has_jpeg? && has_svg? + it "can block specific operations" do + # Block all loaders except jpeg + Vips.block("VipsForeignLoad", true) + Vips.block("VipsForeignLoadJpeg", false) + expect { Vips::Image.new_from_file(svg_image) }.to raise_error Vips::Error, /svgload/ + expect { Vips::Image.new_from_file(jpg_image) }.not_to raise_error + + # Unblock all loaders + Vips.block("VipsForeignLoad", false) + expect { Vips::Image.new_from_file(svg_image) }.not_to raise_error + end + end +end diff --git a/spec/image_spec.rb b/spec/image_spec.rb index 2fe5721..38fdb29 100644 --- a/spec/image_spec.rb +++ b/spec/image_spec.rb @@ -1,9 +1,5 @@ require "spec_helper" -def has_jpeg? - Vips.type_find("VipsOperation", "jpegload") != nil -end - RSpec.describe Vips::Image do it "can save an image to a file" do filename = timg "x.v" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2bb5693..76227b0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,14 @@ def timg(name) File.join(@temp_dir, name) end +def has_jpeg? + Vips.type_find("VipsOperation", "jpegload") != nil +end + +def has_svg? + Vips.type_find("VipsOperation", "svgload") != nil +end + RSpec.configure do |config| config.around do |example| Dir.mktmpdir("ruby-vips-spec-") do |dir|