pngcheck 0.2.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c72fadb4388ddc071725dbc397c884b7157613b79c486f31eb72ec9479ffaabe
4
+ data.tar.gz: 0cabd5da57d57827a2e583b49fdd0157f4709c582d121cb910a0e3b2b6519ca9
5
+ SHA512:
6
+ metadata.gz: cfa764f9784879974d98d8b54f6fcabaacd37f2803b1ed73c5ce598d5f1f724e6bb09d350ed00db5a325e6e4246744082fa6c12b41898b4650d051e411134cba
7
+ data.tar.gz: c29dfd8c21c234721f623144cb5b09f00738b2e43e24cd17ba7b5da1867bfd1bf7f01ba13eac4c593b4224897d135e38d07d2f82ad4f1a6fae05191690ccaa25
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: x64-mingw32
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.dll
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: []