Coder Social home page Coder Social logo

pngcheck-ruby's Introduction

test-and-release

PngCheck: PNG, JNG and MNG integrity checks

The pngcheck gem provides the PngCheck Ruby library, used to

  • verify the integrity of PNG, JNG and MNG files, through

    • checking the internal 32-bit CRCs ("checksums");

    • decompressing the image data;

  • dump almost all of the chunk-level information in the image in human-readable form, including:

    • print the basic statistics about an image (dimensions, bit depth, etc.);

    • list the color and transparency info in its palette (assuming it has one); or

    • to extract the embedded text annotations.

The PngCheck Ruby library is a wrapper around the original pngcheck tool from the libpng project.

Note
PngCheck incorporates pngcheck version 3.0.3, as provided on the official website: http://www.libpng.org/pub/png/apps/pngcheck.html
Note
The PngCheck Ruby library does not distribute nor modify the pngcheck GPL executables pngsplit and png-fix-IDAT-windowsize, and hence is not bound under the GPL license.

Installation

Add this line to your application’s Gemfile:

gem 'pngcheck'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install pngcheck

Usage

PngCheck status codes

PngCheck::STATUS_OK = 0
PngCheck::STATUS_WARNING = 1        # an error in some circumstances but not in all
PngCheck::STATUS_MINOR_ERROR = 3    # minor spec errors (e.g., out-of-range values)
PngCheck::STATUS_MAJOR_ERROR = 4    # file corruption, invalid chunk length/layout, etc.
PngCheck::STATUS_CRITICAL_ERROR = 5 # unexpected EOF or other file(system) error

File processing

status, info = PngCheck.analyze_file("spec/examples/correct.png")

Where:

  • status is file status code

  • info is either file content information for correct files, or error message for corrupt files

valid = PngCheck.check_file("spec/examples/correct.png")

Where:

  • valid is true if the file is correct

  • otherwise an exception is raised. Possible exception types are PngCheck::EmptyPngError, PngCheck::CorruptPngError

Memory buffer processing

data = File.binread("spec/examples/correct.png")
status, info = PngCheck.analyze_buffer(data)

Where:

  • status is the PngCheck status code

  • info is either file content information for correct files, or the error message for corrupt files

data = File.binread("spec/examples/correct.png")
valid = PngCheck.check_buffer(data)

Where:

  • valid is true if the buffer is correct image

  • otherwise an exception is raised. Possible exception types are PngCheck::EmptyPngError, PngCheck::CorruptPngError

Both exception classes have additional status attribute that is set to one of STATUX_XXX codes described above. We believe that exceptions with STATUS_WARNING can be ignored in the majority of applications.

Pre-validation with libpng-ruby

libpng-ruby is the Ruby wrapper library around libpng, commonly used to process PNG files in Ruby.

To prevent crashing libpng-ruby with corrupt PNG files, you may wish to pre-verify integrity of the PNG file before loading it with libpng-ruby. Any errors in the PNG will cause a PngCheck::CorruptPngError to be raised, hence skipping the libpng code.

The mechanism to do so is demonstrated below:

require 'png'
encoded = File.binread("spec/examples/correct.png")

begin
  PngCheck.check_buffer(encoded)
  dec = PNG::Decoder.new
  raw = dec << encoded
rescue PngCheck::CorruptPngError => e
  puts "Exception #{e.message}"
end

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/pngcheck-ruby.

License

Open-sourced under the Ribose BSD-2 clause license. Copyright Ribose for all code excluding the pngcheck library.

The pngcheck library is provided under its original license as unmodified code, its license is located here.

Note
The core code of the pngcheck library is licensed under the libpng 3-clause BSD license, while two additional executables pngsplit and png-fix-IDAT-windowsize are offered under GPL. Since the PngCheck Ruby library does not offer the GPL executables, the gem itself is offered under a BSD license instead of GPL.

pngcheck-ruby's People

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pngcheck-ruby's Issues

pngcheck is breaking on selected plantuml output

https://github.com/metanorma/metanorma-standoc/runs/8192708855?check_suite_focus=true

The PNG images generated via plantuml from standoc on Windows, and one Ruby version of Ubuntu, are failing the pngcheck validation that I've just introduced. This issue is holding up Metanorma release.

The code involved generates Plantuml from YAML files. I would start by investigating whether Plantuml output is valid under pngcheck in Windows at all.

The two PlantUML files are:

[plantuml,title=Common models to be used in this standard]
....
@startuml





'******* IMPORTS ******************************************************
!include /Users/nickn/.../metanorma-standoc/spec/examples/datamodel/models/views/../style.uml.inc


'******* CLASS DEFINITIONS ********************************************
class Localization {
+locale: iso19115PT_Locale
+script: iso15924Code
+textDirection: TextDirectionCode
}

class Validity {
+validityBegins: iso19115CI_Date
+validityEnds: iso19115CI_Date
+revision: iso19115CI_Date
}

class Signature {
+algorithm: iso14888Oid
+publicKey: Uri
+signature: CharacterString
}

enum TextDirectionCode <<enumeration>> {
  leftToRightTopToBottom
  rightToLeftTopToBottom
  leftToRightBottomToTop
  rightToLeftBottomToTop
}


'******* CLASS RELATIONS **********************************************
Localization  -[hidden]->  Validity
Signature  -[hidden]->  Localization


'******* FIDELITY *****************************************************





@enduml
...

and

[plantuml,title=Address profile model overview in UML]
....
@startuml



'******* CLASS GROUPS *************************************************

together {

class AddressProfile

}

together {

class InterchangeAddressClassProfile

class AddressClassProfile

class AddressComponentProfile

}

together {

class AddressComponentSpecification

}

together {

class ProfileCompliantAddress

class ProfileCompliantAddressComponent

}

together {

class Address

class AddressComponent

}


'******* IMPORTS ******************************************************
!include /Users/nickn/Documents/Arbeit/upwork/ribose/metanorma-standoc/spec/examples/datamodel/models/views/../style.uml.inc


'******* CLASS DEFINITIONS ********************************************
class Address {

}

class AddressComponent {

}

class ProfileCompliantAddress {

}

class ProfileCompliantAddressComponent {

}

class AddressProfile {
+country: iso3166Code[0..*]
}

class AddressClassProfile {
+id: CharacterString
+type: CharacterString
+description: CharacterString
+localization: Localization
+signature: Signature[0..1]
+areaApplicability: iso19115MD_SpatialRepresentation[0..*]
+timeToLive: Integer
+validity: Validity
}

class InterchangeAddressClassProfile {

}

class AddressComponentProfile {
+key: CharacterString
+description: CharacterString
+example: CharacterString[0..1]
}

class AddressComponentSpecification {
+maxCardinality: Integer
+minCardinality: Integer
}

class AttributeProfile {
+name: CharacterString
+minCardinality: Integer[0..1]
+maxCardinality: Integer[0..1]
+valueType: CharacterString[0..1]
}


'******* CLASS RELATIONS **********************************************
Address  o-->  AddressComponent : comprises >
ProfileCompliantAddress  --|>  Address
ProfileCompliantAddress  o-->  ProfileCompliantAddressComponent : comprises > 
(ProfileCompliantAddress, ProfileCompliantAddressComponent) . AddressComponentSpecification
ProfileCompliantAddressComponent  --|>  AddressComponent
AddressProfile \"+componentProfile 0..*\" o--  AddressComponentProfile : defines >
AddressProfile \"+addressProfile 0..*\" o--  AddressClassProfile : defines >
AddressClassProfile \"+addressClassProfile\" o--> \"+attributeProfile 0..*\" AttributeProfile
AddressClassProfile \"+profile \" -->  ProfileCompliantAddress : < compliesWith
InterchangeAddressClassProfile  --|>  AddressClassProfile
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileSignature
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileAddressFeature
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileValidity
InterchangeAddressClassProfile  o-- \"+formTemplate 0..*\" FormTemplate : defines >
InterchangeAddressClassProfile  o-- \"+displayTemplate 0..*\" DisplayTemplate : defines >
AddressComponentProfile  --o \"+componentProfile 0..*\" AddressClassProfile : < uses 
(AddressComponentProfile, AddressClassProfile) . AddressComponentSpecification
AddressComponentProfile \"+addressClassProfile\" o--> \"+attributeProfile 0..*\" AttributeProfile
AddressComponentProfile  --> \"+profile \" ProfileCompliantAddressComponent : < compliesWith
InterchangeAddressClassProfile  -[hidden]right-  AddressClassProfile
AddressClassProfile  -[hidden]right-  AddressComponentProfile
ProfileCompliantAddress  -[hidden]right-  ProfileCompliantAddressComponent
Address  -[hidden]right-  AddressComponent
AddressProfile  -[hidden]down-  AddressClassProfile
AddressClassProfile  -[hidden]down-  ProfileCompliantAddress
AddressComponentProfile  -[hidden]down-  AddressComponentSpecification
AddressComponentSpecification  -[hidden]down-  ProfileCompliantAddressComponent
ProfileCompliantAddress  -[hidden]down-  Address
ProfileCompliantAddressComponent  -[hidden]down-  AddressComponent


'******* FIDELITY *****************************************************

hide AttributeProfileSignature

hide AttributeProfileAddressFeature

hide AttributeProfileValidity

hide FormTemplate

hide DisplayTemplate

hide members




@enduml
....[plantuml,title=Address profile model overview in UML]
....
@startuml



'******* CLASS GROUPS *************************************************

together {

class AddressProfile

}

together {

class InterchangeAddressClassProfile

class AddressClassProfile

class AddressComponentProfile

}

together {

class AddressComponentSpecification

}

together {

class ProfileCompliantAddress

class ProfileCompliantAddressComponent

}

together {

class Address

class AddressComponent

}


'******* IMPORTS ******************************************************
!include /Users/nickn/Documents/Arbeit/upwork/ribose/metanorma-standoc/spec/examples/datamodel/models/views/../style.uml.inc


'******* CLASS DEFINITIONS ********************************************
class Address {

}

class AddressComponent {

}

class ProfileCompliantAddress {

}

class ProfileCompliantAddressComponent {

}

class AddressProfile {
+country: iso3166Code[0..*]
}

class AddressClassProfile {
+id: CharacterString
+type: CharacterString
+description: CharacterString
+localization: Localization
+signature: Signature[0..1]
+areaApplicability: iso19115MD_SpatialRepresentation[0..*]
+timeToLive: Integer
+validity: Validity
}

class InterchangeAddressClassProfile {

}

class AddressComponentProfile {
+key: CharacterString
+description: CharacterString
+example: CharacterString[0..1]
}

class AddressComponentSpecification {
+maxCardinality: Integer
+minCardinality: Integer
}

class AttributeProfile {
+name: CharacterString
+minCardinality: Integer[0..1]
+maxCardinality: Integer[0..1]
+valueType: CharacterString[0..1]
}


'******* CLASS RELATIONS **********************************************
Address  o-->  AddressComponent : comprises >
ProfileCompliantAddress  --|>  Address
ProfileCompliantAddress  o-->  ProfileCompliantAddressComponent : comprises > 
(ProfileCompliantAddress, ProfileCompliantAddressComponent) . AddressComponentSpecification
ProfileCompliantAddressComponent  --|>  AddressComponent
AddressProfile \"+componentProfile 0..*\" o--  AddressComponentProfile : defines >
AddressProfile \"+addressProfile 0..*\" o--  AddressClassProfile : defines >
AddressClassProfile \"+addressClassProfile\" o--> \"+attributeProfile 0..*\" AttributeProfile
AddressClassProfile \"+profile \" -->  ProfileCompliantAddress : < compliesWith
InterchangeAddressClassProfile  --|>  AddressClassProfile
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileSignature
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileAddressFeature
InterchangeAddressClassProfile \"+attributeProfile\" o--> \"+addressClassProfile\" AttributeProfileValidity
InterchangeAddressClassProfile  o-- \"+formTemplate 0..*\" FormTemplate : defines >
InterchangeAddressClassProfile  o-- \"+displayTemplate 0..*\" DisplayTemplate : defines >
AddressComponentProfile  --o \"+componentProfile 0..*\" AddressClassProfile : < uses 
(AddressComponentProfile, AddressClassProfile) . AddressComponentSpecification
AddressComponentProfile \"+addressClassProfile\" o--> \"+attributeProfile 0..*\" AttributeProfile
AddressComponentProfile  --> \"+profile \" ProfileCompliantAddressComponent : < compliesWith
InterchangeAddressClassProfile  -[hidden]right-  AddressClassProfile
AddressClassProfile  -[hidden]right-  AddressComponentProfile
ProfileCompliantAddress  -[hidden]right-  ProfileCompliantAddressComponent
Address  -[hidden]right-  AddressComponent
AddressProfile  -[hidden]down-  AddressClassProfile
AddressClassProfile  -[hidden]down-  ProfileCompliantAddress
AddressComponentProfile  -[hidden]down-  AddressComponentSpecification
AddressComponentSpecification  -[hidden]down-  ProfileCompliantAddressComponent
ProfileCompliantAddress  -[hidden]down-  Address
ProfileCompliantAddressComponent  -[hidden]down-  AddressComponent


'******* FIDELITY *****************************************************

hide AttributeProfileSignature

hide AttributeProfileAddressFeature

hide AttributeProfileValidity

hide FormTemplate

hide DisplayTemplate

hide members




@enduml
....

Package `pngcheck` source code during gem build process

On platforms that do not have precompiled binary gems, the pngcheck gem needs to download the pngcheck source code from a remote location.

def files_to_load_all
@files << {
url: "http://www.libpng.org/pub/png/src/pngcheck-3.0.3.tar.gz",
sha256: "c36a4491634af751f7798ea421321642f9590faa032eccb0dd5fb4533609dee6", # rubocop:disable Layout/LineLength
}
end
def files_to_load_cross
if target_platform.eql?("aarch64-linux") &&
!host_platform.eql?("aarch64-linux")
@files << {
url: "http://ports.ubuntu.com/pool/main/z/zlib/zlib1g-dev_1.2.11.dfsg-2ubuntu1.3_arm64.deb", # rubocop:disable Layout/LineLength
sha256: "0ebadc1ff2a70f0958d4e8e21ffa97d9fa4da23555eaae87782e963044a26fcf", # rubocop:disable Layout/LineLength
}
end
end

However, this makes the installation process dependent on the libpng.org site, e.g. if the link goes down the gem users won't be able to install the pngcheck gem.

This issue is to bundle the source code within the gem (e.g. as a tar.gz).

Image generated by PlantUML via Metanorma identified as corrupt

There is a pngcheck check that is currently saying that a PNG image generated by plantuml is invalid, which is somewhat blocking the release of metanorma.

https://github.com/metanorma/metanorma-standoc/runs/8192708855?check_suite_focus=true

image

The particular failing PNG image is provided here.

Interestingly, this is only failing on Ubuntu + Ruby 3.0 and Windows.

We want to know whether:

  • is pngcheck functioning properly on these platforms?
  • is pngcheck being overly strict here? Or is there a "lenient mode"?
  • is this image really broken? If so we will need to get rid of it from our tests.
<image src="data:image/png;base64,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" id="_c9a5cdf7-e38c-e20d-195e-c62ea33b7cd5" mimetype="image/png" height="auto" width="auto"/>

Implement pngcheck Ruby gem

As a wrapper around the excellent pngcheck http://www.libpng.org/pub/png/apps/pngcheck.html

This will be a gem that only provides one method to determine whether the image is valid or not, e.g.

# Valid PNG
PngCheck.check_file(filepath) => true

# Invalid PNG
PngCheck.check_file(filepath)
=> raise PngCheck::CorruptPngError.new("
  chunk IHDR at offset 0x0000c, length 13
    2250 x 922 image, 32-bit RGB+alpha, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk cHRM at offset 0x00035, length 32
    White x = 0.3127 y = 0.329,  Red x = 0.64 y = 0.33
    Green x = 0.3 y = 0.6,  Blue x = 0.15 y = 0.06
  chunk pHYs at offset 0x00061, length 9: 9448x9448 pixels/meter (240 dpi)
  chunk bKGD at offset 0x00076, length 2:  invalid length
")

In the future we can integrate with libpng-ruby like this:

require 'png'
dec = PNG::Decoder.new(:color_type => :BGR)
raw = dec << IO.binread("test.png") 
PngCheck.check(raw)

Build zlib locally during cross-compilation

Build zlib locally during cross-compilation (like excavate, for example) and not attempt to download deb package manually since the version and the name of the package changes rapidly

Implement pngcheck `check_file` method

Now that the FFI binding is created and compilation works we need to implement the check_file (or verify_file, or another more appropriate name?) method.

The check_file method takes a file path, loads the path and checks the file.

# Valid PNG
PngCheck.check_file(filepath) => true

# Invalid PNG
PngCheck.check_file(filepath)
=> raise PngCheck::CorruptPngError.new("
  chunk IHDR at offset 0x0000c, length 13
    2250 x 922 image, 32-bit RGB+alpha, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk cHRM at offset 0x00035, length 32
    White x = 0.3127 y = 0.329,  Red x = 0.64 y = 0.33
    Green x = 0.3 y = 0.6,  Blue x = 0.15 y = 0.06
  chunk pHYs at offset 0x00061, length 9: 9448x9448 pixels/meter (240 dpi)
  chunk bKGD at offset 0x00076, length 2:  invalid length
")

macOS Screenshot application generates invalid PNG files

For example, this file is invalid.

Screen Shot 2022-09-12 at 8 13 24 PM

Screen Shot 2022-09-12 at 8.13.24 PM.png  illegal (unless recently approved) unknown, public chunk iDOT
ERROR: Screen Shot 2022-09-12 at 8.13.24 PM.png

However I'm having a hard time believing that the Screenshot app generates an invalid PNG.

@maxirmx any thoughts here?

Implement integration with `libpng-ruby`

After #4 we need to integrate with checking file in memory after loading the file. (in #4 the file load happens within pngcheck)

We can integrate with libpng-ruby like this:

require 'png'
dec = PNG::Decoder.new(:color_type => :BGR)
raw = dec << IO.binread("test.png") 
PngCheck.check(raw)

Skip shared library check if file command is not available

On Docker linux/amd64, I get:

apt-get update
apt-get install -y ruby ruby-dev make libffi-dev zlib1g-dev
gem install pngcheck
...
Building native extensions. This could take a while...
ERROR:  Error installing pngcheck:
	ERROR: Failed to build gem native extension.

    current directory: /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/ext
/usr/bin/ruby3.0 -I /usr/lib/ruby/vendor_ruby -r ./siteconf20220913-9390-t0culf.rb extconf.rb
Downloading pngcheck-3.0.3.tar.gz (  6%) 
Extracting pngcheck-3.0.3.tar.gz into tmp/x86_64-linux-gnu/ports/pngcheck/3.0.3... OK
Running 'compile' for pngcheck 3.0.3... OK
/usr/lib/ruby/3.0.0/open3.rb:221:in `spawn': No such file or directory - file (Errno::ENOENT)
	from /usr/lib/ruby/3.0.0/open3.rb:221:in `popen_run'
	from /usr/lib/ruby/3.0.0/open3.rb:160:in `popen2'
	from /usr/lib/ruby/3.0.0/open3.rb:350:in `capture2'
	from /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/lib/pngcheck/recipe.rb:71:in `block in verify_libs'
	from /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/lib/pngcheck/recipe.rb:70:in `each'
	from /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/lib/pngcheck/recipe.rb:70:in `verify_libs'
	from /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/lib/pngcheck/recipe.rb:89:in `install'
	from /var/lib/gems/3.0.0/gems/mini_portile2-2.8.0/lib/mini_portile2/mini_portile.rb:188:in `cook'
	from /var/lib/gems/3.0.0/gems/pngcheck-0.2.5/lib/pngcheck/recipe.rb:49:in `cook'
	from extconf.rb:7:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /var/lib/gems/3.0.0/gems/pngcheck-0.2.5 for inspection.
Results logged to /var/lib/gems/3.0.0/extensions/x86_64-linux/3.0.0/pngcheck-0.2.5/gem_make.out

Originally posted by @ronaldtse in https://github.com/metanorma/SWF-Corpus_and_IEEEP2874-D2/issues/7#issuecomment-1245676564

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.