diff --git a/CHANGELOG.md b/CHANGELOG.md index 418179f..c3e3182 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,15 @@ Squib follows [semantic versioning](http://semver.org). ## v0.15.0 / Unreleased -## v0.14.2 / Unreleased +Features: +* Added check for malformed PNG files (#250, #218) + +Docs: +* Documented the n-sided-ness of polygons and stars + +Special thanks to @lcarlsen + +## v0.14.2 / 2018-08-01 Features: * Sprues for DriveThruCards and printandplaygames!! (#247, from @blinks) diff --git a/lib/squib/graphics/image.rb b/lib/squib/graphics/image.rb index 7bfb719..3b10599 100644 --- a/lib/squib/graphics/image.rb +++ b/lib/squib/graphics/image.rb @@ -6,10 +6,25 @@ module Squib # @api private def cache_load_image(file) @img_cache ||= {} - @img_cache[file] || @img_cache[file] = Cairo::ImageSurface.from_png(file) + @img_cache[file] ||= open_png file end module_function :cache_load_image + # Open a PNG file, checking magic bytes if it's a real PNG + # Magic bytes taken from: + # https://en.wikipedia.org/wiki/List_of_file_signatures + # :nodoc: + # @api private + PNG_MAGIC = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] + def open_png(file) + if PNG_MAGIC == File.read(file, 8).bytes + return Cairo::ImageSurface.from_png(file) + else + raise ArgumentError.new("ERROR: #{file} is not a PNG file") + end + end + module_function :open_png + class Card # :nodoc: diff --git a/spec/data/images/a.png b/spec/data/images/a.png new file mode 100644 index 0000000..883be2f Binary files /dev/null and b/spec/data/images/a.png differ diff --git a/spec/data/images/not_a_png.txt b/spec/data/images/not_a_png.txt new file mode 100644 index 0000000..51bb107 --- /dev/null +++ b/spec/data/images/not_a_png.txt @@ -0,0 +1 @@ +Not a PNG. diff --git a/spec/graphics/image_magicbytes_check.rb b/spec/graphics/image_magicbytes_check.rb new file mode 100644 index 0000000..869d276 --- /dev/null +++ b/spec/graphics/image_magicbytes_check.rb @@ -0,0 +1,20 @@ +require 'spec_helper' +require 'squib/graphics/image' + +describe Squib do + context :open_png do + + it 'opens a real image file' do + file = image_file('a.png') + expect(Squib.open_png(file)).to respond_to(:format) # loaded? + end + + it 'fails on a non-PNG file' do + file = image_file('not_a_png.txt') + expect { Squib.open_png(file) }. + to raise_error(ArgumentError, /is not a PNG file/) + + end + + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4f8b912..5c4fb9a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -42,6 +42,10 @@ def csv_file(file) "#{File.expand_path(File.dirname(__FILE__))}/data/csv/#{file}" end +def image_file(file) + "#{File.expand_path(File.dirname(__FILE__))}/data/images/#{file}" +end + def xlsx_file(file) "#{File.expand_path(File.dirname(__FILE__))}/data/xlsx/#{file}" end