pngcheck 0.2.1-x86_64-darwin

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 27062afad7417e03ea6d53e0aa9368d8008999a18c59d080fc0758c0ba95e616
4
+ data.tar.gz: 4781232e73a38165f618afa1f65dc9ed767eda8b7f2a830b32d1d40d41218f6f
5
+ SHA512:
6
+ metadata.gz: 5e33c4ac19ad4654f701d4ea96844c1c7b77a9faf7aa40c20e79e37a001492a9300104470c1b4006d7d8aca417e1ec4d5e63fb21c3e128460a459e3c97de7fe3
7
+ data.tar.gz: 57635821f813e367e4c112e43bdafbb2767742922f92b28befca78bcec2eb87238fac74b9e8f8b5cb2a784f391a62347b4dc6f67c1e1ec83247c90de68f460f5
data/.cross_rubies ADDED
@@ -0,0 +1,6 @@
1
+ x64-mingw32
2
+ x86_64-linux
3
+ aarch64-linux
4
+ x86_64-darwin
5
+ arm64-darwin
6
+ x64-mingw-ucrt
data/.hound.yml ADDED
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ enabled: true
3
+ config_file: .rubocop.yml
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ inherit_from:
2
+ - 'https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml'
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.7
6
+ SuggestExtensions: false
7
+
8
+ Gemspec/RequireMFA:
9
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in pngcheck.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,53 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2022, Ribose Inc.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
27
+
28
+ This module includes original pngcheck software [http://www.libpng.org/pub/png/apps/pngcheck.html]
29
+ that is distributed under the follwoing license:
30
+
31
+ Copyright 1995-2020 by Alexander Lehmann <lehmann@usa.net>,
32
+ Andreas Dilger <adilger@enel.ucalgary.ca>,
33
+ Glenn Randers-Pehrson <randeg@alum.rpi.edu>,
34
+ Greg Roelofs <newt@pobox.com>,
35
+ John Bowler <jbowler@acm.org>,
36
+ Tom Lane <tgl@sss.pgh.pa.us>
37
+
38
+ Permission to use, copy, modify, and distribute this software and its
39
+ documentation for any purpose and without fee is hereby granted, provided
40
+ that the above copyright notice appear in all copies and that both that
41
+ copyright notice and this permission notice appear in supporting
42
+ documentation. This software is provided "as is" without express or
43
+ implied warranty.
44
+
45
+
46
+ [This license applies to pngcheck.c and its associated makefiles and
47
+ documentation in the main directory. The files in the "gpl" subdirectory--
48
+ specifically, pngsplit.c and png-fix-IDAT-windowsize.c--are licensed under the
49
+ GNU General Public License. The files in "amiga" subdirectory are Copyright
50
+ 2003 Simon Goodwin and were contributed without an explicit license statement,
51
+ but insofar as the "gpl" subdirectory didn't exist at the time, it's safe to
52
+ assume their intended license was similar to pngcheck's, just with Simon's
53
+ copyright replacing the one above.]
data/README.adoc ADDED
@@ -0,0 +1,161 @@
1
+ image:https://github.com/metanorma/pngcheck-ruby/actions/workflows/test-and-release.yml/badge.svg["test-and-release", link="https://github.com/metanorma/pngcheck-ruby/actions/workflows/test-and-release.yml"]
2
+
3
+ == PngCheck: PNG, JNG and MNG integrity checks
4
+
5
+ The `pngcheck` gem provides the `PngCheck` Ruby library, used to
6
+
7
+ * verify the integrity of PNG, JNG and MNG files, through
8
+
9
+ ** checking the internal 32-bit CRCs ("checksums");
10
+ ** decompressing the image data;
11
+
12
+ * dump *almost* all of the chunk-level information in the image in
13
+ human-readable form, including:
14
+
15
+ ** print the basic statistics about an image (dimensions, bit depth, etc.);
16
+ ** list the color and transparency info in its palette (assuming it has one); or
17
+ ** to extract the embedded text annotations.
18
+
19
+ The `PngCheck` Ruby library is a wrapper around the original
20
+ http://www.libpng.org/pub/png/apps/pngcheck.html[`pngcheck`] tool
21
+ from the http://www.libpng.org/pub/png/libpng.html[`libpng`] project.
22
+
23
+ NOTE: `PngCheck` incorporates
24
+ http://www.libpng.org/pub/png/apps/pngcheck.html[`pngcheck`] version 3.0.3, as
25
+ provided on the official website:
26
+ http://www.libpng.org/pub/png/apps/pngcheck.html
27
+
28
+ NOTE: The `PngCheck` Ruby library does not distribute nor modify the `pngcheck`
29
+ GPL executables `pngsplit` and `png-fix-IDAT-windowsize`, and hence is not bound
30
+ under the GPL license.
31
+
32
+ === Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ [source,ruby]
37
+ ----
38
+ gem 'pngcheck'
39
+ ----
40
+
41
+ And then execute:
42
+
43
+ [source,sh]
44
+ ----
45
+ $ bundle install
46
+ ----
47
+
48
+ Or install it yourself as:
49
+ [source,sh]
50
+ ----
51
+ $ gem install pngcheck
52
+ ----
53
+
54
+ === Usage
55
+
56
+ ==== PngCeck status codes
57
+
58
+ [source,ruby]
59
+ ----
60
+ PngCheck::STATUS_OK = 0
61
+ PngCheck::STATUS_WARNING = 1 # an error in some circumstances but not in all
62
+ PngCheck::STATUS_MINOR_ERROR = 3 # minor spec errors (e.g., out-of-range values)
63
+ PngCheck::STATUS_MAJOR_ERROR = 4 # file corruption, invalid chunk length/layout, etc.
64
+ PngCheck::STATUS_CRITICAL_ERROR = 5 # unexpected EOF or other file(system) error
65
+ ----
66
+
67
+ ==== File processing
68
+
69
+ [source,ruby]
70
+ ----
71
+ status, info = PngCheck.analyze_file("spec/examples/correct.png")
72
+ ----
73
+
74
+ Where:
75
+
76
+ * `status` is file status code
77
+ * `info` is either file content information for correct files, or error message for corrupt files
78
+
79
+ [source,ruby]
80
+ ----
81
+ valid = PngCheck.check_file("spec/examples/correct.png")
82
+ ----
83
+
84
+ Where:
85
+
86
+ * `valid` is `true` if the file is correct
87
+ * otherwise an exception of type `PngCheck::CorruptPngError` is raised
88
+
89
+
90
+ ==== Memory buffer processing
91
+
92
+ [source,ruby]
93
+ ----
94
+ data = File.binread("spec/examples/correct.png")
95
+ status, info = PngCheck.analyze_buffer(data)
96
+ ----
97
+
98
+ Where:
99
+
100
+ * `status` is the PngCheck status code
101
+ * `info` is either file content information for correct files, or the error
102
+ message for corrupt files
103
+
104
+
105
+ [source,ruby]
106
+ ----
107
+ data = File.binread("spec/examples/correct.png")
108
+ valid = PngCheck.check_buffer(data)
109
+ ----
110
+
111
+ Where:
112
+
113
+ * `valid` is `true` if the file is correct
114
+ * otherwise an exception of type `PngCheck::CorruptPngError` is raised
115
+
116
+
117
+ ==== Pre-validation with libpng-ruby
118
+
119
+ `libpng-ruby` is the Ruby wrapper library around `libpng`, commonly used to
120
+ process PNG files in Ruby.
121
+
122
+ To prevent crashing libpng-ruby with corrupt PNG files, you may wish to
123
+ pre-verify integrity of the PNG file before loading it with `libpng-ruby`.
124
+ Any errors in the PNG will cause a `PngCheck::CorruptPngError` to be raised,
125
+ hence skipping the `libpng` code.
126
+
127
+ The mechanism to do so is demonstrated below:
128
+
129
+ [source,ruby]
130
+ ----
131
+ require 'png'
132
+ encoded = File.binread("spec/examples/correct.png")
133
+
134
+ begin
135
+ PngCheck.check_buffer(encoded)
136
+ dec = PNG::Decoder.new
137
+ raw = dec << encoded
138
+ rescue PngCheck::CorruptPngError => e
139
+ puts "Exception #{e.message}"
140
+ end
141
+ ----
142
+
143
+
144
+ === Contributing
145
+
146
+ Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/pngcheck-ruby.
147
+
148
+ === License
149
+
150
+ Open-sourced under the link:LICENSE.txt[Ribose BSD-2 clause license].
151
+ Copyright Ribose for all code excluding the `pngcheck` library.
152
+
153
+ The `pngcheck` library is provided under its original license as unmodified
154
+ code, its license is located
155
+ http://www.libpng.org/pub/png/src/pngcheck-3.0.3.LICENSE[here].
156
+
157
+ NOTE: The core code of the `pngcheck` library is licensed under the
158
+ http://www.libpng.org/pub/png/src/libpng-LICENSE.txt[libpng 3-clause BSD license],
159
+ while two additional executables `pngsplit` and `png-fix-IDAT-windowsize` are
160
+ offered under GPL. Since the `PngCheck` Ruby library does not offer the GPL
161
+ executables, the gem itself is offered under a BSD license instead of GPL.
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: %i[spec rubocop]
11
+
12
+ task :compile do
13
+ require_relative "ext/extconf"
14
+ end
15
+
16
+ task spec: :compile
17
+
18
+ desc "Build install-compilation gem"
19
+ task "gem:native:any" do
20
+ sh "rake platform:any gem"
21
+ end
22
+
23
+ require "rubygems/package_task"
24
+
25
+ desc "Define the gem task to build on any platform (compile on install)"
26
+ task "platform:any" do
27
+ spec = Gem::Specification::load("pngcheck.gemspec").dup
28
+ task = Gem::PackageTask.new(spec)
29
+ task.define
30
+ end
31
+
32
+ File.readlines(".cross_rubies", chomp: true).each do |platform|
33
+ desc "Build pre-compiled gem for the #{platform} platform"
34
+ task "gem:native:#{platform}" do
35
+ sh "rake compile platform:#{platform} gem target_platform=#{platform}"
36
+ end
37
+
38
+ desc "Define the gem task to build on the #{platform} platform (binary gem)"
39
+ task "platform:#{platform}" do
40
+ spec = Gem::Specification::load("pngcheck.gemspec").dup
41
+ spec.platform = Gem::Platform.new(platform)
42
+ spec.files += Dir.glob("lib/pngcheck/*.{dll,so,dylib}")
43
+ spec.extensions = []
44
+ spec.dependencies.reject! { |d| d.name == "mini_portile2" }
45
+
46
+ task = Gem::PackageTask.new(spec)
47
+ task.define
48
+ end
49
+ end
50
+
51
+ require "rake/clean"
52
+
53
+ CLOBBER.include("pkg")
54
+ CLEAN.include("ports",
55
+ "tmp",
56
+ "lib/pngcheck/*.dll",
57
+ "lib/pngcheck/*.dylib",
58
+ "lib/pngcheck/*.so")
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "pngcheck"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/ext/Makefile ADDED
@@ -0,0 +1,4 @@
1
+ # dummy Makefile, it is required to build an extension
2
+ all:
3
+ clean:
4
+ install:
data/ext/extconf.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
4
+
5
+ require "pngcheck/recipe"
6
+
7
+ recipe = PngCheck::Recipe.new
8
+ recipe.cook
data/ext/wrapper.c ADDED
@@ -0,0 +1,106 @@
1
+ #ifdef _WIN32
2
+ # include <windows.h>
3
+ # include <share.h>
4
+ # include <io.h>
5
+ # include <stdio.h>
6
+ #endif
7
+
8
+ #include <sys/stat.h>
9
+ #include <fcntl.h>
10
+ #include <errno.h>
11
+
12
+ #ifdef _WIN32
13
+ /* https://github.com/Arryboom/fmemopen_windows */
14
+
15
+ FILE *fmemopen(void *buf, size_t len, char *type) {
16
+ int fd;
17
+ FILE *fp;
18
+ char tp[MAX_PATH - 13];
19
+ char fn[MAX_PATH + 1];
20
+ int * pfd = &fd;
21
+ int retner = -1;
22
+ char tfname[] = "MemTF_";
23
+ if (!GetTempPathA(sizeof(tp), tp)) return NULL;
24
+ if (!GetTempFileNameA(tp, tfname, 0, fn)) return NULL;
25
+ retner = _sopen_s(pfd, fn, _O_CREAT | _O_SHORT_LIVED | _O_TEMPORARY | _O_RDWR | _O_BINARY | _O_NOINHERIT, _SH_DENYRW, _S_IREAD | _S_IWRITE);
26
+ if (retner != 0) return NULL;
27
+ if (fd == -1) return NULL;
28
+ fp = _fdopen(fd, "wb+");
29
+ if (!fp) {
30
+ _close(fd);
31
+ return NULL;
32
+ }
33
+ fwrite(buf, len, 1, fp);
34
+ rewind(fp);
35
+ return fp;
36
+ }
37
+ #endif
38
+
39
+ #include "pngcheck.c"
40
+
41
+ #define EXTRA_MESSAGE_SIZE 1024
42
+
43
+ void failed_to_open(char *extra_msg, char *fname) {
44
+ snprintf(extra_msg, EXTRA_MESSAGE_SIZE, "Failed to open %s: %s\n", fname, strerror(errno));
45
+ extra_msg[EXTRA_MESSAGE_SIZE-1] = 0;
46
+ }
47
+
48
+ void failed_to_dup(char *extra_msg, char *fmt) {
49
+ snprintf(extra_msg, EXTRA_MESSAGE_SIZE, fmt, strerror(errno));
50
+ extra_msg[EXTRA_MESSAGE_SIZE-1] = 0;
51
+ }
52
+
53
+ int pngcheck_inner(FILE* fp, char *fname, char *cname, char *extra_msg) {
54
+ int rc = kCriticalError;
55
+ int fd = open(cname, O_WRONLY);
56
+ if (fd == -1) {
57
+ failed_to_open(extra_msg, cname);
58
+ }
59
+ else {
60
+ int stdout_copy = dup(STDOUT_FILENO);
61
+ if (stdout_copy == -1) {
62
+ failed_to_dup(extra_msg, "Failed to save stdout: %s\n");
63
+ }
64
+ else {
65
+ if (dup2(fd, STDOUT_FILENO) == -1) {
66
+ failed_to_dup(extra_msg, "Failed to reassign stdout: %s\n");
67
+ }
68
+ else {
69
+ rc = pngcheck(fp, fname, 0, NULL);
70
+ fflush(stdout);
71
+ }
72
+ dup2(stdout_copy, STDOUT_FILENO);
73
+ }
74
+ close(fd);
75
+ }
76
+ return rc;
77
+ }
78
+
79
+ int pngcheck_file(char *fname, char *cname, char *extra_msg) {
80
+ int rc = kCriticalError;
81
+ extra_msg[0] = 0;
82
+ FILE* fp = fopen(fname, "rb");
83
+ if (fp == NULL) {
84
+ failed_to_open(extra_msg, fname);
85
+ }
86
+ else {
87
+ rc = pngcheck_inner(fp, fname, cname, extra_msg);
88
+ fclose(fp);
89
+ }
90
+ return rc;
91
+ }
92
+
93
+ int pngcheck_buffer(char *data, int size, char *cname, char *extra_msg) {
94
+ int rc = kCriticalError;
95
+ extra_msg[0] = 0;
96
+ char* fname = "[memory buffer]";
97
+ FILE* fp = fmemopen(data, size, "rb");
98
+ if (fp == NULL) {
99
+ failed_to_open(extra_msg, fname);
100
+ }
101
+ else {
102
+ rc = pngcheck_inner(fp, fname, cname, extra_msg);
103
+ fclose(fp);
104
+ }
105
+ return rc;
106
+ }
Binary file
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+ require "mini_portile2"
5
+ require "pathname"
6
+ require "tmpdir"
7
+ require "shellwords"
8
+ require "open3"
9
+ require_relative "version"
10
+
11
+ module PngCheck
12
+ class Recipe < MiniPortile
13
+ ROOT = Pathname.new(File.expand_path("../..", __dir__))
14
+ COMMON_FLAGS = "-shared -fPIC -Wall -O -DUSE_ZLIB"
15
+
16
+ def files_to_load
17
+ @files << {
18
+ url: "http://www.libpng.org/pub/png/src/pngcheck-3.0.3.tar.gz",
19
+ sha256: "c36a4491634af751f7798ea421321642f9590faa032eccb0dd5fb4533609dee6", # rubocop:disable Layout/LineLength
20
+ }
21
+ if target_platform.eql?("aarch64-linux")
22
+ @files << {
23
+ url: "http://ports.ubuntu.com/pool/main/z/zlib/zlib1g-dev_1.2.11.dfsg-2ubuntu1.3_arm64.deb", # rubocop:disable Layout/LineLength
24
+ sha256: "0ebadc1ff2a70f0958d4e8e21ffa97d9fa4da23555eaae87782e963044a26fcf", # rubocop:disable Layout/LineLength
25
+ }
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ super("pngcheck", "3.0.3")
31
+ files_to_load
32
+ @target = ROOT.join(@target).to_s
33
+ @printed = {}
34
+ end
35
+
36
+ def make_cmd
37
+ if MiniPortile.windows?
38
+ "gcc #{COMMON_FLAGS} -o pngcheck.dll wrapper.c -lz"
39
+ else
40
+ "#{cc} #{cflags} #{COMMON_FLAGS} -o pngcheck.so wrapper.c -lz"
41
+ end
42
+ end
43
+
44
+ def cook_if_not
45
+ cook unless File.exist?(checkpoint)
46
+ end
47
+
48
+ def cook
49
+ super
50
+ FileUtils.touch(checkpoint)
51
+ end
52
+
53
+ def checkpoint
54
+ File.join(@target, "#{name}-#{version}-#{host}.installed")
55
+ end
56
+
57
+ def configure
58
+ FileUtils.cp(ROOT.join("ext", "wrapper.c"), work_path, verbose: false)
59
+ if target_platform.eql?("aarch64-linux")
60
+ extract_file("#{work_path}/../data.tar.xz", work_path.to_s)
61
+ end
62
+ end
63
+
64
+ def libs_to_verify
65
+ Dir.glob(ROOT.join("lib", "pngcheck",
66
+ "pngcheck.{so,dylib,dll}"))
67
+ end
68
+
69
+ def verify_libs
70
+ libs_to_verify.each do |l|
71
+ out, st = Open3.capture2("file #{l}")
72
+ out = out.strip
73
+
74
+ raise "Failed to query file #{l}: #{out}" unless st.exitstatus.zero?
75
+
76
+ if out.include?(target_format)
77
+ message("Verifying #{l} ... OK\n")
78
+ else
79
+ raise "Invalid file format '#{out}', '#{@target_format}' expected"
80
+ end
81
+ end
82
+ end
83
+
84
+ def install
85
+ libs = Dir.glob(File.join(work_path, "*"))
86
+ .grep(%r{/(?:lib)?[a-zA-Z0-9\-]+\.(?:so|dylib|dll)$})
87
+
88
+ FileUtils.cp_r(libs, ROOT.join("lib", "pngcheck"), verbose: false)
89
+ verify_libs
90
+ end
91
+
92
+ def execute(action, command, command_opts = {})
93
+ super(action, command, command_opts.merge(debug: false))
94
+ end
95
+
96
+ def message(text)
97
+ return super unless text.start_with?("\rDownloading")
98
+
99
+ match = text.match(/(\rDownloading .*)\(\s*\d+%\)/)
100
+ pattern = match ? match[1] : text
101
+ return if @printed[pattern]
102
+
103
+ @printed[pattern] = true
104
+ super
105
+ end
106
+
107
+ # rubocop:disable Metrics/MethodLength
108
+ # rubocop:disable Metrics/CyclomaticComplexity
109
+ def host_platform
110
+ @host_platform ||=
111
+ case @host
112
+ when /\Ax86_64-w64-mingw32/
113
+ "x64-mingw32"
114
+ when /\Ax86_64-w64-mingw-ucrt/
115
+ "x64-mingw-ucrt"
116
+ when /\Ax86_64.*linux/
117
+ "x86_64-linux"
118
+ when /\A(arm64|aarch64).*linux/
119
+ "aarch64-linux"
120
+ when /\Ax86_64.*(darwin|macos|osx)/
121
+ "x86_64-darwin"
122
+ when /\A(arm64|aarch64).*(darwin|macos|osx)/
123
+ "arm64-darwin"
124
+ else
125
+ @host
126
+ end
127
+ end
128
+
129
+ def target_platform
130
+ @target_platform ||=
131
+ case ENV.fetch("target_platform", nil)
132
+ when /\A(arm64|aarch64).*(darwin|macos|osx)/
133
+ "arm64-darwin"
134
+ when /\Ax86_64.*(darwin|macos|osx)/
135
+ "x86_64-darwin"
136
+ when /\A(arm64|aarch64).*linux/
137
+ "aarch64-linux"
138
+ else
139
+ ENV.fetch("target_platform", host_platform)
140
+ end
141
+ end
142
+
143
+ def target_format
144
+ @target_format ||=
145
+ case target_platform
146
+ when "arm64-darwin"
147
+ "Mach-O 64-bit dynamically linked shared library arm64"
148
+ when "x86_64-darwin"
149
+ "Mach-O 64-bit dynamically linked shared library x86_64"
150
+ when "aarch64-linux"
151
+ "ELF 64-bit LSB shared object, ARM aarch64"
152
+ when "x86_64-linux"
153
+ "ELF 64-bit LSB shared object, x86-64"
154
+ when /\Ax64-mingw(32|-ucrt)/
155
+ "PE32+ executable (DLL) (console) x86-64, for MS Windows"
156
+ else
157
+ "skip"
158
+ end
159
+ end
160
+
161
+ def cc
162
+ @cc ||=
163
+ if target_platform.eql?(host_platform)
164
+ "gcc"
165
+ else
166
+ case target_platform
167
+ when "aarch64-linux"
168
+ "aarch64-linux-gnu-gcc"
169
+ when "arm64-darwin"
170
+ "gcc -target arm64-apple-macos11"
171
+ else
172
+ "gcc"
173
+ end
174
+ end
175
+ end
176
+
177
+ def cflags
178
+ @cflags ||=
179
+ if target_platform.eql?(host_platform) ||
180
+ !target_platform.eql?("aarch64-linux")
181
+ ""
182
+ else
183
+ "-I./usr/include -L./usr/lib/#{target_platform}-gnu"
184
+ end
185
+ end
186
+ # rubocop:enable Metrics/CyclomaticComplexity
187
+ # rubocop:enable Metrics/MethodLength
188
+ end
189
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PngCheck
4
+ VERSION = "0.2.1"
5
+ end
data/lib/pngcheck.rb ADDED
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+ require "tempfile"
5
+ require_relative "pngcheck/version"
6
+
7
+ module PngCheck
8
+ class CorruptPngError < StandardError; end
9
+
10
+ STATUS_OK = 0
11
+ STATUS_WARNING = 1 # an error in some circumstances but not in all
12
+ STATUS_MINOR_ERROR = 3 # minor spec errors (e.g., out-of-range values)
13
+ STATUS_MAJOR_ERROR = 4 # file corruption, invalid chunk length/layout, etc.
14
+ STATUS_CRITICAL_ERROR = 5 # unexpected EOF or other file(system) error
15
+
16
+ EXTRA_MESSAGE_SIZE = 1024
17
+
18
+ extend FFI::Library
19
+
20
+ lib_filename = FFI::Platform.windows? ? "pngcheck.dll" : "pngcheck.so"
21
+ ffi_lib File.expand_path("pngcheck/#{lib_filename}", __dir__)
22
+ .gsub("/", File::ALT_SEPARATOR || File::SEPARATOR)
23
+
24
+ # int pngcheck_file(char *fname, char *cname, char *extra_message)
25
+ typedef :string, :file_path
26
+ typedef :pointer, :extra_message
27
+ typedef :int, :status
28
+ attach_function :pngcheck_file, %i[file_path file_path extra_message],
29
+ :status
30
+ # int pngcheck_string(char *data, int size, char *cname, char *extra_message)
31
+ typedef :pointer, :data
32
+ typedef :int, :size
33
+ attach_function :pngcheck_buffer, %i[data size file_path extra_message],
34
+ :status
35
+
36
+ @@semaphore = Mutex.new
37
+
38
+ class << self
39
+ def analyze_file(path)
40
+ Tempfile.open("captured-stream-") do |captured_stream|
41
+ extra_msg = FFI::Buffer.alloc_out(EXTRA_MESSAGE_SIZE, 1, false)
42
+ @@semaphore.lock
43
+ status = pngcheck_file(path, captured_stream.path, extra_msg)
44
+ @@semaphore.unlock
45
+ # we assume that pngcheck_file returns either captured_stream
46
+ # or extra message but not both
47
+ [status, captured_stream.read + extra_msg.get_string(16)]
48
+ end
49
+ end
50
+
51
+ def check_file(path)
52
+ status, info = analyze_file(path)
53
+ raise CorruptPngError.new info unless status == STATUS_OK
54
+
55
+ true
56
+ end
57
+
58
+ def analyze_buffer(data)
59
+ Tempfile.open("captured-stream-") do |captured_stream|
60
+ extra_msg = FFI::Buffer.alloc_out(EXTRA_MESSAGE_SIZE, 1, false)
61
+ mem_buf = FFI::MemoryPointer.new(:char, data.bytesize)
62
+ mem_buf.put_bytes(0, data)
63
+ @@semaphore.lock
64
+ status = pngcheck_buffer(mem_buf, data.bytesize, captured_stream.path,
65
+ extra_msg)
66
+ @@semaphore.unlock
67
+ [status, captured_stream.read + extra_msg.get_string(16)]
68
+ end
69
+ end
70
+
71
+ def check_buffer(data)
72
+ status, info = analyze_buffer(data)
73
+ raise CorruptPngError.new info unless status == STATUS_OK
74
+
75
+ true
76
+ end
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pngcheck
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: x86_64-darwin
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: libpng-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.4'
83
+ description:
84
+ email:
85
+ - open.source@ribose.com
86
+ executables:
87
+ - console
88
+ - setup
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".cross_rubies"
93
+ - ".hound.yml"
94
+ - ".rspec"
95
+ - ".rubocop.yml"
96
+ - Gemfile
97
+ - LICENSE.txt
98
+ - README.adoc
99
+ - Rakefile
100
+ - bin/console
101
+ - bin/setup
102
+ - ext/Makefile
103
+ - ext/extconf.rb
104
+ - ext/wrapper.c
105
+ - lib/pngcheck.rb
106
+ - lib/pngcheck/pngcheck.so
107
+ - lib/pngcheck/recipe.rb
108
+ - lib/pngcheck/version.rb
109
+ homepage: https://github.com/metanorma/pngcheck-ruby
110
+ licenses:
111
+ - BSD-2-Clause
112
+ metadata:
113
+ homepage_uri: https://github.com/metanorma/pngcheck-ruby
114
+ source_code_uri: https://github.com/metanorma/pngcheck-ruby
115
+ changelog_uri: https://github.com/metanorma/pngcheck-ruby
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 2.7.0
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubygems_version: 3.1.6
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Ruby interface to pngcheck.
135
+ test_files: []