pngcheck 0.2.8-x86_64-linux-musl

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: 99b15c73419c0c64c81007716c57888bf46f685d4346b00d7d8fef14dc783124
4
+ data.tar.gz: be2d20075c6839497f8defbd8a35c5a36077e8c6950c03bfcfa72e7db31acd71
5
+ SHA512:
6
+ metadata.gz: 10be40e02108840529bcec19ea80063db0a7074a0791e60bc6337acb6844f5c21cbc8a2ad792669edd546d0fe62ae82a7e4fe8d7c949a7e6f386545ad842f57b
7
+ data.tar.gz: 3aca24064a31cc004dd186cd55aa464d459e6d520a4d4ccfbd7c56865f521d811fa15112e2f21a24542f777da8ad177113fae1803cbabeab2a75a41f99ac2c3a
data/.cross_rubies ADDED
@@ -0,0 +1,8 @@
1
+ x64-mingw32
2
+ x86_64-linux
3
+ x86_64-linux-musl
4
+ aarch64-linux
5
+ aarch64-linux-musl
6
+ x86_64-darwin
7
+ arm64-darwin
8
+ 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
+ ==== PngCheck 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 is raised. Possible exception types are `PngCheck::EmptyPngError`, `PngCheck::CorruptPngError`
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 buffer is correct image
114
+ * otherwise an exception is raised. Possible exception types are `PngCheck::EmptyPngError`, `PngCheck::CorruptPngError`
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,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+ require_relative "ext/layout"
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ RuboCop::RakeTask.new
10
+
11
+ task default: %i[spec rubocop]
12
+
13
+ task :compile do
14
+ require_relative "ext/extconf"
15
+ end
16
+
17
+ task spec: :compile
18
+
19
+ desc "Build install-compilation gem"
20
+ task "gem:native:any" do
21
+ sh "rake platform:any gem"
22
+ end
23
+
24
+ desc "Download pngcheck source"
25
+ task :pngcheck do
26
+ test_cmd = "test -f #{PNGCHECK_LOCAL}"
27
+ wget_cmd = "wget -nc -nv -O #{PNGCHECK_LOCAL} #{PNGCHECK_URI}"
28
+ sh "#{test_cmd} || #{wget_cmd}"
29
+ end
30
+ task compile: :pngcheck
31
+
32
+ require "rubygems/package_task"
33
+
34
+ desc "Define the gem task to build on any platform (compile on install)"
35
+ task "platform:any" do
36
+ spec = Gem::Specification::load("pngcheck.gemspec").dup
37
+ spec.files << PNGCHECK_LOCAL
38
+ task = Gem::PackageTask.new(spec)
39
+ task.define
40
+ end
41
+ task "gem:native:any": :pngcheck
42
+
43
+ File.readlines(".cross_rubies", chomp: true).each do |platform|
44
+ desc "Build pre-compiled gem for the #{platform} platform"
45
+ task "gem:native:#{platform}" do
46
+ sh "rake compile platform:#{platform} gem target_platform=#{platform}"
47
+ end
48
+
49
+ desc "Define the gem task to build on the #{platform} platform (binary gem)"
50
+ task "platform:#{platform}" do
51
+ spec = Gem::Specification::load("pngcheck.gemspec").dup
52
+ spec.platform = Gem::Platform.new(platform)
53
+ spec.files += Dir.glob("lib/pngcheck/*.{dll,so,dylib}")
54
+ spec.extensions = []
55
+ spec.dependencies.reject! { |d| d.name == "mini_portile2" }
56
+
57
+ task = Gem::PackageTask.new(spec)
58
+ task.define
59
+ end
60
+ end
61
+
62
+ require "rake/clean"
63
+
64
+ CLOBBER.include("pkg")
65
+ CLEAN.include("ports",
66
+ "tmp",
67
+ PNGCHECK_LOCAL,
68
+ "lib/pngcheck/*.dll",
69
+ "lib/pngcheck/*.dylib",
70
+ "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/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("bundle", __dir__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rspec-core", "rspec")
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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
4
+ require "pngcheck/recipe"
5
+
6
+ recipe = PngCheck::Recipe.new
7
+ recipe.cook
data/ext/layout.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ PNGCHECK_ARCH = "pngcheck-3.0.3.tar.gz"
4
+ PNGCHECK_URI = "http://www.libpng.org/pub/png/src/#{PNGCHECK_ARCH}"
5
+ PNGCHECK_LOCAL = "ext/#{PNGCHECK_ARCH}"
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,212 @@
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
+ ROOT = Pathname.new(File.expand_path("../..", __dir__))
12
+ require "#{ROOT}/ext/layout.rb"
13
+
14
+ module PngCheck
15
+ class Recipe < MiniPortile
16
+ COMMON_FLAGS = "-shared -fPIC -Wall -O -DUSE_ZLIB"
17
+
18
+ def files_to_load_all
19
+ @files << {
20
+ url: "file:#{ROOT}/#{PNGCHECK_LOCAL}", # "http://www.libpng.org/pub/png/src/pngcheck-3.0.3.tar.gz"
21
+ sha256: "c36a4491634af751f7798ea421321642f9590faa032eccb0dd5fb4533609dee6", # rubocop:disable Layout/LineLength
22
+ }
23
+ end
24
+
25
+ def files_to_load_cross
26
+ if target_platform.eql?("aarch64-linux") &&
27
+ !host_platform.eql?("aarch64-linux")
28
+ @files << {
29
+ url: "http://ports.ubuntu.com/pool/main/z/zlib/zlib1g-dev_1.2.11.dfsg-2ubuntu1.3_arm64.deb", # rubocop:disable Layout/LineLength
30
+ sha256: "0ebadc1ff2a70f0958d4e8e21ffa97d9fa4da23555eaae87782e963044a26fcf", # rubocop:disable Layout/LineLength
31
+ }
32
+ end
33
+ end
34
+
35
+ def initialize
36
+ super("pngcheck", "3.0.3")
37
+ files_to_load_all
38
+ files_to_load_cross
39
+ @target = ROOT.join(@target).to_s
40
+ @printed = {}
41
+ end
42
+
43
+ def lib_filename
44
+ @lib_filename ||=
45
+ if MiniPortile.windows?
46
+ "pngcheck.dll"
47
+ else
48
+ "pngcheck.so"
49
+ end
50
+ end
51
+
52
+ def lib_workpath
53
+ @lib_workpath ||= File.join(work_path, lib_filename)
54
+ end
55
+
56
+ def make_cmd
57
+ "#{cc} #{cflags} #{COMMON_FLAGS} -o #{lib_filename} wrapper.c -lz"
58
+ end
59
+
60
+ def cook_if_not
61
+ cook unless File.exist?(checkpoint)
62
+ end
63
+
64
+ def cook
65
+ super
66
+ FileUtils.touch(checkpoint)
67
+ end
68
+
69
+ def download_file_file(uri, full_path)
70
+ if MiniPortile.windows?
71
+ FileUtils.mkdir_p File.dirname(full_path)
72
+ FileUtils.cp uri.to_s.delete_prefix("file:"), full_path
73
+ else
74
+ super
75
+ end
76
+ end
77
+
78
+ def tmp_path
79
+ "tmp/#{@host}/ports"
80
+ end
81
+
82
+ def checkpoint
83
+ File.join(@target, "#{name}-#{version}-#{host}.installed")
84
+ end
85
+
86
+ def configure
87
+ FileUtils.cp(ROOT.join("ext", "wrapper.c"), work_path, verbose: false)
88
+ if target_platform.eql?("aarch64-linux") &&
89
+ !host_platform.eql?("aarch64-linux")
90
+ extract_file("#{work_path}/../data.tar.xz", work_path.to_s)
91
+ end
92
+ end
93
+
94
+ def verify_lib
95
+ begin
96
+ out, = Open3.capture2("file #{lib_workpath}")
97
+ rescue StandardError
98
+ message("Failed to call file, skipped library verification ...\n")
99
+ return
100
+ end
101
+
102
+ unless out.include?(target_format)
103
+ raise "Invalid file format '#{out.strip}', '#{@target_format}' expected"
104
+ end
105
+
106
+ message("Verifying #{lib_workpath} ... OK\n")
107
+ end
108
+
109
+ def install
110
+ libs = Dir.glob(File.join(work_path, "*"))
111
+ .grep(%r{/(?:lib)?[a-zA-Z0-9\-]+\.(?:so|dylib|dll)$})
112
+
113
+ FileUtils.cp_r(libs, ROOT.join("lib", "pngcheck"), verbose: false)
114
+ verify_lib
115
+ end
116
+
117
+ def execute(action, command, command_opts = {})
118
+ super(action, command, command_opts.merge(debug: false))
119
+ end
120
+
121
+ def message(text)
122
+ return super unless text.start_with?("\rDownloading")
123
+
124
+ match = text.match(/(\rDownloading .*)\(\s*\d+%\)/)
125
+ pattern = match ? match[1] : text
126
+ return if @printed[pattern]
127
+
128
+ @printed[pattern] = true
129
+ super
130
+ end
131
+
132
+ # rubocop:disable Metrics/MethodLength
133
+ # rubocop:disable Metrics/CyclomaticComplexity
134
+ def host_platform
135
+ @host_platform ||=
136
+ case @host
137
+ when /\Ax86_64-w64-mingw32/
138
+ "x64-mingw32"
139
+ when /\Ax86_64-w64-mingw-ucrt/
140
+ "x64-mingw-ucrt"
141
+ when /\A(arm64|aarch64).*linux/
142
+ "aarch64-linux"
143
+ when /\Ax86_64.*(darwin|macos|osx)/
144
+ "x86_64-darwin"
145
+ when /\A(arm64|aarch64).*(darwin|macos|osx)/
146
+ "arm64-darwin"
147
+ else
148
+ @host
149
+ end
150
+ end
151
+
152
+ def target_platform
153
+ @target_platform ||=
154
+ case ENV.fetch("target_platform", nil)
155
+ when /\A(arm64|aarch64).*(darwin|macos|osx)/
156
+ "arm64-darwin"
157
+ when /\Ax86_64.*(darwin|macos|osx)/
158
+ "x86_64-darwin"
159
+ when /\A(arm64|aarch64).*linux/
160
+ "aarch64-linux"
161
+ else
162
+ ENV.fetch("target_platform", host_platform)
163
+ end
164
+ end
165
+
166
+ def target_format
167
+ @target_format ||=
168
+ case target_platform
169
+ when "arm64-darwin"
170
+ "Mach-O 64-bit dynamically linked shared library arm64"
171
+ when "x86_64-darwin"
172
+ "Mach-O 64-bit dynamically linked shared library x86_64"
173
+ when "aarch64-linux"
174
+ "ELF 64-bit LSB shared object, ARM aarch64"
175
+ when /\Ax86_64.*linux.*/
176
+ "ELF 64-bit LSB shared object, x86-64"
177
+ when /\Ax64-mingw(32|-ucrt)/
178
+ "PE32+ executable (DLL) (console) x86-64, for MS Windows"
179
+ else
180
+ "skip"
181
+ end
182
+ end
183
+
184
+ def cc
185
+ @cc ||=
186
+ if target_platform.eql?(host_platform)
187
+ "gcc"
188
+ else
189
+ case target_platform
190
+ when "aarch64-linux"
191
+ "aarch64-linux-gnu-gcc"
192
+ when "arm64-darwin"
193
+ "gcc -target arm64-apple-macos11"
194
+ else
195
+ "gcc"
196
+ end
197
+ end
198
+ end
199
+
200
+ def cflags
201
+ @cflags ||=
202
+ if target_platform.eql?("aarch64-linux") &&
203
+ !host_platform.eql?("aarch64-linux")
204
+ "-I./usr/include -L./usr/lib/#{target_platform}-gnu"
205
+ else
206
+ ""
207
+ end
208
+ end
209
+ # rubocop:enable Metrics/CyclomaticComplexity
210
+ # rubocop:enable Metrics/MethodLength
211
+ end
212
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PngCheck
4
+ VERSION = "0.2.8"
5
+ end
data/lib/pngcheck.rb ADDED
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+ require "tempfile"
5
+ require_relative "pngcheck/version"
6
+
7
+ module PngCheck
8
+ EMPTY_IMAGE = "Image is empty"
9
+
10
+ class CorruptPngError < StandardError; end
11
+
12
+ class EmptyPngError < StandardError
13
+ def initialize(msg = EMPTY_IMAGE)
14
+ super
15
+ end
16
+ end
17
+
18
+ STATUS_OK = 0
19
+ STATUS_WARNING = 1 # an error in some circumstances but not in all
20
+ STATUS_MINOR_ERROR = 3 # minor spec errors (e.g., out-of-range values)
21
+ STATUS_MAJOR_ERROR = 4 # file corruption, invalid chunk length/layout, etc.
22
+ STATUS_CRITICAL_ERROR = 5 # unexpected EOF or other file(system) error
23
+
24
+ EXTRA_MESSAGE_SIZE = 1024
25
+
26
+ extend FFI::Library
27
+
28
+ lib_filename = FFI::Platform.windows? ? "pngcheck.dll" : "pngcheck.so"
29
+ ffi_lib File.expand_path("pngcheck/#{lib_filename}", __dir__)
30
+ .gsub("/", File::ALT_SEPARATOR || File::SEPARATOR)
31
+
32
+ # int pngcheck_file(char *fname, char *cname, char *extra_message)
33
+ typedef :string, :file_path
34
+ typedef :pointer, :extra_message
35
+ typedef :int, :status
36
+ attach_function :pngcheck_file, %i[file_path file_path extra_message],
37
+ :status
38
+ # int pngcheck_string(char *data, int size, char *cname, char *extra_message)
39
+ typedef :pointer, :data
40
+ typedef :int, :size
41
+ attach_function :pngcheck_buffer, %i[data size file_path extra_message],
42
+ :status
43
+
44
+ @@semaphore = Mutex.new
45
+
46
+ class << self
47
+ def analyze_file(path)
48
+ return [STATUS_CRITICAL_ERROR, EMPTY_IMAGE] if File.zero? path
49
+
50
+ do_analyze_file(path)
51
+ end
52
+
53
+ def check_file(path)
54
+ status, info = analyze_file(path)
55
+ raise EmptyPngError.new if info.eql? EMPTY_IMAGE
56
+ raise CorruptPngError.new info unless status == STATUS_OK
57
+
58
+ true
59
+ end
60
+
61
+ def analyze_buffer(data)
62
+ return [STATUS_CRITICAL_ERROR, EMPTY_IMAGE] if data.empty?
63
+
64
+ do_analyze_buffer(data)
65
+ end
66
+
67
+ def check_buffer(data)
68
+ status, info = analyze_buffer(data)
69
+ raise EmptyPngError.new if info.eql? EMPTY_IMAGE
70
+ raise CorruptPngError.new info unless status == STATUS_OK
71
+
72
+ true
73
+ end
74
+
75
+ private
76
+
77
+ def do_analyze_file(path)
78
+ Tempfile.open("captured-stream-") do |captured_stream|
79
+ extra_msg = FFI::Buffer.alloc_out(EXTRA_MESSAGE_SIZE, 1, false)
80
+ @@semaphore.lock
81
+ status = pngcheck_file(path, captured_stream.path, extra_msg)
82
+ @@semaphore.unlock
83
+ # we assume that pngcheck_file returns either captured_stream
84
+ # or extra message but not both
85
+
86
+ [status, captured_stream.read + extra_msg.get_string(0)]
87
+ end
88
+ end
89
+
90
+ def do_analyze_buffer(data)
91
+ Tempfile.open("captured-stream-") do |captured_stream|
92
+ extra_msg = FFI::Buffer.alloc_out(EXTRA_MESSAGE_SIZE, 1, false)
93
+ mem_buf = FFI::MemoryPointer.new(:char, data.bytesize)
94
+ mem_buf.put_bytes(0, data)
95
+ @@semaphore.lock
96
+ status = pngcheck_buffer(mem_buf, data.bytesize, captured_stream.path,
97
+ extra_msg)
98
+ @@semaphore.unlock
99
+ [status, captured_stream.read + extra_msg.get_string(0)]
100
+ end
101
+ end
102
+ end
103
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pngcheck
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.8
5
+ platform: x86_64-linux-musl
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.3.22
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.3.22
33
+ - !ruby/object:Gem::Dependency
34
+ name: ffi
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '13.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '13.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: libpng-ruby
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.6'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.6'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.4'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.4'
103
+ description:
104
+ email:
105
+ - open.source@ribose.com
106
+ executables:
107
+ - console
108
+ - rspec
109
+ - setup
110
+ extensions: []
111
+ extra_rdoc_files: []
112
+ files:
113
+ - ".cross_rubies"
114
+ - ".hound.yml"
115
+ - ".rspec"
116
+ - ".rubocop.yml"
117
+ - Gemfile
118
+ - LICENSE.txt
119
+ - README.adoc
120
+ - Rakefile
121
+ - bin/console
122
+ - bin/rspec
123
+ - bin/setup
124
+ - ext/Makefile
125
+ - ext/extconf.rb
126
+ - ext/layout.rb
127
+ - ext/wrapper.c
128
+ - lib/pngcheck.rb
129
+ - lib/pngcheck/pngcheck.so
130
+ - lib/pngcheck/recipe.rb
131
+ - lib/pngcheck/version.rb
132
+ homepage: https://github.com/metanorma/pngcheck-ruby
133
+ licenses:
134
+ - BSD-2-Clause
135
+ metadata:
136
+ homepage_uri: https://github.com/metanorma/pngcheck-ruby
137
+ source_code_uri: https://github.com/metanorma/pngcheck-ruby
138
+ changelog_uri: https://github.com/metanorma/pngcheck-ruby
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: 2.7.0
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubygems_version: 3.3.7
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: Ruby interface to pngcheck.
158
+ test_files: []