From 2e9dc1469338aabcf5931c8ffd21608782e102fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Rosick=C3=BD?= Date: Sat, 12 Jun 2021 18:49:57 +0200 Subject: [PATCH 01/13] jruby support --- .github/workflows/ci.yml | 1 + .gitignore | 3 + README.md | 2 + Rakefile | 24 +- digest.gemspec | 36 +- ext/digest/bubblebabble/lib/bubblebabble.rb | 9 + ext/digest/lib/digest.rb | 8 +- ext/digest/md5/lib/md5.rb | 9 + ext/digest/rmd160/lib/rmd160.rb | 9 + ext/digest/sha1/lib/sha1.rb | 9 + ext/digest/sha2/lib/sha2.rb | 7 +- .../org/jruby/ext/digest/BubbleBabble.java | 119 +++++ .../org/jruby/ext/digest/DigestLibrary.java | 43 ++ ext/java/org/jruby/ext/digest/MD5.java | 41 ++ ext/java/org/jruby/ext/digest/RMD160.java | 41 ++ ext/java/org/jruby/ext/digest/RubyDigest.java | 498 ++++++++++++++++++ ext/java/org/jruby/ext/digest/SHA1.java | 41 ++ ext/java/org/jruby/ext/digest/SHA2.java | 41 ++ test/lib/core_assertions.rb | 1 + 19 files changed, 926 insertions(+), 16 deletions(-) create mode 100644 ext/digest/bubblebabble/lib/bubblebabble.rb create mode 100644 ext/digest/md5/lib/md5.rb create mode 100644 ext/digest/rmd160/lib/rmd160.rb create mode 100644 ext/digest/sha1/lib/sha1.rb create mode 100644 ext/java/org/jruby/ext/digest/BubbleBabble.java create mode 100644 ext/java/org/jruby/ext/digest/DigestLibrary.java create mode 100644 ext/java/org/jruby/ext/digest/MD5.java create mode 100644 ext/java/org/jruby/ext/digest/RMD160.java create mode 100644 ext/java/org/jruby/ext/digest/RubyDigest.java create mode 100644 ext/java/org/jruby/ext/digest/SHA1.java create mode 100644 ext/java/org/jruby/ext/digest/SHA2.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e02190b..fbae97b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: - { os: ubuntu-20.04, ruby: head, ignore-pkg-error: true } - { os: windows-latest, ruby: mingw, ignore-pkg-error: true } - { os: windows-latest, ruby: mswin, ignore-pkg-error: true } + - { os: ubuntu-20.04, ruby: jruby-head, ignore-pkg-error: true } exclude: - { os: windows-latest, ruby: debug } diff --git a/.gitignore b/.gitignore index ed2d6bc..3e810e4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ /pkg/ /spec/reports/ /tmp/ +lib/*.jar +lib/digest +lib/digest/*.rb *.bundle *.so *.o diff --git a/README.md b/README.md index 8b73e9a..a7ea58e 100644 --- a/README.md +++ b/README.md @@ -95,3 +95,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/d ## License The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). + +Files under ext/java (JRuby's digest) are licensed under [Eclipse Public License version 2.0](https://opensource.org/licenses/EPL-2.0), [GNU General Public License version 2](https://opensource.org/licenses/GPL-2.0), [GNU Lesser General Public License version 2.1](https://opensource.org/licenses/LGPL-2.1). diff --git a/Rakefile b/Rakefile index d5c2dab..4e55a63 100644 --- a/Rakefile +++ b/Rakefile @@ -7,10 +7,26 @@ Rake::TestTask.new(:test) do |t| t.test_files = FileList["test/**/test_*.rb"] end -require 'rake/extensiontask' -Rake::ExtensionTask.new("digest") -%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| - Rake::ExtensionTask.new("digest/#{ext}") +if RUBY_ENGINE == 'jruby' + require 'rake/javaextensiontask' + Rake::JavaExtensionTask.new("digest") do |ext| + ext.source_version = '1.8' + ext.target_version = '1.8' + ext.ext_dir = 'ext/java' + end + + # copy library loaders + require 'fileutils' + %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + FileUtils.mkdir "./lib/digest" unless File.exist?("./lib/digest") + FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb" + end +else + require 'rake/extensiontask' + Rake::ExtensionTask.new("digest") + %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + Rake::ExtensionTask.new("digest/#{ext}") + end end task :sync_tool do diff --git a/digest.gemspec b/digest.gemspec index 381df92..a6c6f15 100644 --- a/digest.gemspec +++ b/digest.gemspec @@ -10,7 +10,11 @@ Gem::Specification.new do |spec| spec.summary = %q{Provides a framework for message digest libraries.} spec.description = %q{Provides a framework for message digest libraries.} spec.homepage = "https://github.com/ruby/digest" - spec.licenses = ["Ruby", "BSD-2-Clause"] + if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' + spec.licenses = ["Ruby", "BSD-2-Clause", "EPL-2.0", "GPL-2.0", "LGPL-2.1"] + else + spec.licenses = ["Ruby", "BSD-2-Clause"] + end spec.files = [ "LICENSE.txt", "README.md", @@ -46,13 +50,27 @@ Gem::Specification.new do |spec| spec.bindir = "exe" spec.executables = [] spec.require_paths = ["lib"] - spec.extensions = %w[ - ext/digest/extconf.rb - ext/digest/bubblebabble/extconf.rb - ext/digest/md5/extconf.rb - ext/digest/rmd160/extconf.rb - ext/digest/sha1/extconf.rb - ext/digest/sha2/extconf.rb - ] + + if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' + spec.platform = 'java' + spec.files.concat [ + "lib/digest.jar", + "lib/digest/md5.rb", + "lib/digest/sha1.rb", + "lib/digest/sha2.rb", + "lib/digest/rmd160.rb", + "lib/digest/bubblebabble.rb" + ] + else + spec.extensions = %w[ + ext/digest/extconf.rb + ext/digest/bubblebabble/extconf.rb + ext/digest/md5/extconf.rb + ext/digest/rmd160/extconf.rb + ext/digest/sha1/extconf.rb + ext/digest/sha2/extconf.rb + ] + end + spec.metadata["msys2_mingw_dependencies"] = "openssl" end diff --git a/ext/digest/bubblebabble/lib/bubblebabble.rb b/ext/digest/bubblebabble/lib/bubblebabble.rb new file mode 100644 index 0000000..8ad06c7 --- /dev/null +++ b/ext/digest/bubblebabble/lib/bubblebabble.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false + +require 'digest' + +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.BubbleBabble") +else + require 'digest/bubblebabble.so' +end diff --git a/ext/digest/lib/digest.rb b/ext/digest/lib/digest.rb index ba0637a..9121988 100644 --- a/ext/digest/lib/digest.rb +++ b/ext/digest/lib/digest.rb @@ -1,5 +1,9 @@ # frozen_string_literal: false -require 'digest.so' +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.DigestLibrary") +else + require 'digest.so' +end module Digest # A mutex for Digest(). @@ -8,7 +12,7 @@ module Digest def self.const_missing(name) # :nodoc: case name when :SHA256, :SHA384, :SHA512 - lib = 'digest/sha2.so' + lib = 'digest/sha2' else lib = File.join('digest', name.to_s.downcase) end diff --git a/ext/digest/md5/lib/md5.rb b/ext/digest/md5/lib/md5.rb new file mode 100644 index 0000000..3748f9d --- /dev/null +++ b/ext/digest/md5/lib/md5.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false + +require 'digest' + +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.MD5") +else + require 'digest/md5.so' +end diff --git a/ext/digest/rmd160/lib/rmd160.rb b/ext/digest/rmd160/lib/rmd160.rb new file mode 100644 index 0000000..eabb92a --- /dev/null +++ b/ext/digest/rmd160/lib/rmd160.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false + +require 'digest' + +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.RMD160") +else + require 'digest/rmd160.so' +end diff --git a/ext/digest/sha1/lib/sha1.rb b/ext/digest/sha1/lib/sha1.rb new file mode 100644 index 0000000..864997b --- /dev/null +++ b/ext/digest/sha1/lib/sha1.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false + +require 'digest' + +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.SHA1") +else + require 'digest/sha1.so' +end diff --git a/ext/digest/sha2/lib/sha2.rb b/ext/digest/sha2/lib/sha2.rb index 61a0734..22e0997 100644 --- a/ext/digest/sha2/lib/sha2.rb +++ b/ext/digest/sha2/lib/sha2.rb @@ -11,7 +11,12 @@ # $Id$ require 'digest' -require 'digest/sha2.so' + +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.digest.SHA2") +else + require 'digest/sha2.so' +end module Digest # diff --git a/ext/java/org/jruby/ext/digest/BubbleBabble.java b/ext/java/org/jruby/ext/digest/BubbleBabble.java new file mode 100644 index 0000000..27b457c --- /dev/null +++ b/ext/java/org/jruby/ext/digest/BubbleBabble.java @@ -0,0 +1,119 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2010 Charles Oliver Nutter + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; +import org.jruby.util.ByteList; + +import java.io.IOException; + +public class BubbleBabble implements Library { + + public void load(final Ruby runtime, boolean wrap) throws IOException { + RubyDigest.createDigestBubbleBabble(runtime); + } + + /** + * Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987) + * + * OpenSSH License Notice + * + * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2008 Alexander von Gernler. All rights reserved. + * Copyright (c) 2010,2011 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + public static ByteList bubblebabble(byte[] message, int begin, int length) { + char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'}; + char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', + 'n', 'p', 'r', 's', 't', 'v', 'z', 'x'}; + + long seed = 1; + + ByteList retval = new ByteList(); + + int rounds = (length / 2) + 1; + retval.append('x'); + for (int i = 0; i < rounds; i++) { + int idx0, idx1, idx2, idx3, idx4; + + if ((i + 1 < rounds) || (length % 2 != 0)) { + long b = message[begin + 2 * i] & 0xFF; + idx0 = (int) ((((b >> 6) & 3) + seed) % 6) & 0xFFFFFFFF; + idx1 = (int) (((b) >> 2) & 15) & 0xFFFFFFFF; + idx2 = (int) (((b & 3) + (seed / 6)) % 6) & 0xFFFFFFFF; + retval.append(vowels[idx0]); + retval.append(consonants[idx1]); + retval.append(vowels[idx2]); + if ((i + 1) < rounds) { + long b2 = message[begin + (2 * i) + 1] & 0xFF; + idx3 = (int) ((b2 >> 4) & 15) & 0xFFFFFFFF; + idx4 = (int) ((b2) & 15) & 0xFFFFFFFF; + retval.append(consonants[idx3]); + retval.append('-'); + retval.append(consonants[idx4]); + seed = ((seed * 5) + + ((b * 7) + + b2)) % 36; + } + } else { + idx0 = (int) (seed % 6) & 0xFFFFFFFF; + idx1 = 16; + idx2 = (int) (seed / 6) & 0xFFFFFFFF; + retval.append(vowels[idx0]); + retval.append(consonants[idx1]); + retval.append(vowels[idx2]); + } + } + retval.append('x'); + + return retval; + } +} diff --git a/ext/java/org/jruby/ext/digest/DigestLibrary.java b/ext/java/org/jruby/ext/digest/DigestLibrary.java new file mode 100644 index 0000000..00f15bf --- /dev/null +++ b/ext/java/org/jruby/ext/digest/DigestLibrary.java @@ -0,0 +1,43 @@ +/***** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2006 Ola Bini + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; + +/** + * @author Ola Bini + */ +public class DigestLibrary implements Library { + public void load(final Ruby runtime, boolean wrap) throws IOException { + org.jruby.ext.digest.RubyDigest.createDigest(runtime); + } +}// DigestLibrary diff --git a/ext/java/org/jruby/ext/digest/MD5.java b/ext/java/org/jruby/ext/digest/MD5.java new file mode 100644 index 0000000..65b6821 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/MD5.java @@ -0,0 +1,41 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2010 Charles Oliver Nutter + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.io.IOException; +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; + +public class MD5 implements Library { + + public void load(final Ruby runtime, boolean wrap) throws IOException { + org.jruby.ext.digest.RubyDigest.createDigestMD5(runtime); + } +} diff --git a/ext/java/org/jruby/ext/digest/RMD160.java b/ext/java/org/jruby/ext/digest/RMD160.java new file mode 100644 index 0000000..abe675c --- /dev/null +++ b/ext/java/org/jruby/ext/digest/RMD160.java @@ -0,0 +1,41 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2010 Charles Oliver Nutter + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.io.IOException; +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; + +public class RMD160 implements Library { + + public void load(final Ruby runtime, boolean wrap) throws IOException { + org.jruby.ext.digest.RubyDigest.createDigestRMD160(runtime); + } +} diff --git a/ext/java/org/jruby/ext/digest/RubyDigest.java b/ext/java/org/jruby/ext/digest/RubyDigest.java new file mode 100644 index 0000000..e60bfca --- /dev/null +++ b/ext/java/org/jruby/ext/digest/RubyDigest.java @@ -0,0 +1,498 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2006, 2007 Ola Bini + * Copyright (C) 2007 Nick Sieger + * Copyright (C) 2008 Vladimir Sizikov + * Copyright (C) 2009 Joseph LaFata + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.util.HashMap; +import java.util.Map; + +import org.jcodings.specific.USASCIIEncoding; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyFixnum; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.RubyString; + +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.anno.JRubyModule; +import org.jruby.exceptions.RaiseException; +import org.jruby.runtime.Block; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ArraySupport; +import org.jruby.util.ByteList; +import org.jruby.util.log.Logger; +import org.jruby.util.log.LoggerFactory; + +/** + * @author Ola Bini + */ +@JRubyModule(name="Digest") +public class RubyDigest { + + private static final Map CLONEABLE_DIGESTS = new HashMap(8, 1); + static { + // standard digests from JCA specification; if we can retrieve and clone, save them + for (String name : new String[] {"MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512"}) { + try { + MessageDigest digest = MessageDigest.getInstance(name); + digest.clone(); + CLONEABLE_DIGESTS.put(name, digest); + } + catch (Exception e) { + logger().debug(name + " not clonable", e); + } + } + } + + private static Logger logger() { return LoggerFactory.getLogger(RubyDigest.class); } + + private static final String PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider"; + private static Provider provider = null; + + public static void createDigest(Ruby runtime) { + try { + provider = (Provider) Class.forName(PROVIDER).getConstructor().newInstance(); + } + catch (Throwable t) { /* provider is not available */ } + + RubyModule mDigest = runtime.defineModule("Digest"); + mDigest.defineAnnotatedMethods(RubyDigest.class); + RubyModule mDigestInstance = mDigest.defineModuleUnder("Instance"); + mDigestInstance.defineAnnotatedMethods(DigestInstance.class); + RubyClass cDigestClass = mDigest.defineClassUnder("Class", runtime.getObject(), DigestClass::new); + cDigestClass.defineAnnotatedMethods(DigestClass.class); + cDigestClass.includeModule(mDigestInstance); + RubyClass cDigestBase = mDigest.defineClassUnder("Base", cDigestClass, DigestBase::new); + cDigestBase.defineAnnotatedMethods(DigestBase.class); + } + + private static MessageDigest createMessageDigest(final String name) throws NoSuchAlgorithmException { + MessageDigest cloneable = CLONEABLE_DIGESTS.get(name); + if (cloneable != null) { + try { + return (MessageDigest) cloneable.clone(); + } + catch (CloneNotSupportedException e) { + // should never happen, since we tested it in static init + } + } + + // fall back on JCA mechanisms for getting a digest + if (provider != null) { + try { + return MessageDigest.getInstance(name, provider); + } + catch (NoSuchAlgorithmException e) { + // bouncy castle doesn't support algorithm + } + } + + // fall back to default JCA providers + return MessageDigest.getInstance(name); + } + + private final static byte[] digits = { + '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z' + }; + + private static ByteList toHex(byte[] val) { + ByteList byteList = new ByteList(val.length * 2); + for (int i = 0, j = val.length; i < j; i++) { + int b = val[i] & 0xFF; + byteList.append(digits[b >> 4]); + byteList.append(digits[b & 0xF]); + } + return byteList; + } + + private static RubyString toHexString(Ruby runtime, byte[] val) { + return RubyString.newStringNoCopy(runtime, new ByteList(ByteList.plain(toHex(val)), USASCIIEncoding.INSTANCE)); + } + + @JRubyMethod(name = "hexencode", required = 1, meta = true) + public static RubyString hexencode(IRubyObject self, IRubyObject arg) { + return toHexString(self.getRuntime(), arg.convertToString().getBytes()); + } + + @JRubyMethod(name = "bubblebabble", required = 1, meta = true) + public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) { + final ByteList bytes = arg.convertToString().getByteList(); + return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(bytes.unsafeBytes(), bytes.begin(), bytes.length())); + } + + private static class Metadata { + + private final String name; + private final int blockLength; + + Metadata(String name, int blockLength) { + this.name = name; + this.blockLength = blockLength; + } + + String getName() { + return name; + } + + int getBlockLength() { + return blockLength; + } + } + + + @JRubyClass(name="Digest::MD5", parent="Digest::Base") + public static class MD5 {} + @JRubyClass(name="Digest::RMD160", parent="Digest::Base") + public static class RMD160 {} + @JRubyClass(name="Digest::SHA1", parent="Digest::Base") + public static class SHA1 {} + @JRubyClass(name="Digest::SHA256", parent="Digest::Base") + public static class SHA256 {} + @JRubyClass(name="Digest::SHA384", parent="Digest::Base") + public static class SHA384 {} + @JRubyClass(name="Digest::SHA512", parent="Digest::Base") + public static class SHA512 {} + + public static void createDigestMD5(Ruby runtime) { + runtime.getLoadService().require("digest"); + RubyModule Digest = runtime.getModule("Digest"); + RubyClass Base = Digest.getClass("Base"); + RubyClass MD5 = Digest.defineClassUnder("MD5", Base, Base.getAllocator()); + MD5.setInternalVariable("metadata", new Metadata("MD5", 64)); + } + + public static void createDigestRMD160(Ruby runtime) { + runtime.getLoadService().require("digest"); + if(provider == null) { + throw runtime.newLoadError("RMD160 not supported without BouncyCastle"); + } + RubyModule Digest = runtime.getModule("Digest"); + RubyClass Base = Digest.getClass("Base"); + RubyClass RMD160 = Digest.defineClassUnder("RMD160", Base, Base.getAllocator()); + RMD160.setInternalVariable("metadata", new Metadata("RIPEMD160", 64)); + } + + public static void createDigestSHA1(Ruby runtime) { + runtime.getLoadService().require("digest"); + RubyModule Digest = runtime.getModule("Digest"); + RubyClass Base = Digest.getClass("Base"); + RubyClass SHA1 = Digest.defineClassUnder("SHA1", Base, Base.getAllocator()); + SHA1.setInternalVariable("metadata", new Metadata("SHA1", 64)); + } + + public static void createDigestSHA2(Ruby runtime) { + runtime.getLoadService().require("digest"); + try { + createMessageDigest("SHA-256"); + } + catch (NoSuchAlgorithmException e) { + RaiseException ex = runtime.newLoadError("SHA2 not supported"); + ex.initCause(e); + throw ex; + } + final RubyModule Digest = runtime.getModule("Digest"); + final RubyClass Base = Digest.getClass("Base"); + RubyClass SHA256 = Digest.defineClassUnder("SHA256", Base, Base.getAllocator()); + SHA256.setInternalVariable("metadata", new Metadata("SHA-256", 64)); + RubyClass SHA384 = Digest.defineClassUnder("SHA384", Base, Base.getAllocator()); + SHA384.setInternalVariable("metadata", new Metadata("SHA-384", 128)); + RubyClass SHA512 = Digest.defineClassUnder("SHA512", Base, Base.getAllocator()); + SHA512.setInternalVariable("metadata", new Metadata("SHA-512", 128)); + } + + public static void createDigestBubbleBabble(Ruby runtime) { + runtime.getLoadService().require("digest"); + RubyModule Digest = runtime.getModule("Digest"); + RubyClass Base = Digest.getClass("Base"); + RubyClass MD5 = Digest.defineClassUnder("BubbleBabble", Base, Base.getAllocator()); + MD5.setInternalVariable("metadata", new Metadata("BubbleBabble", 64)); + } + + @JRubyModule(name = "Digest::Instance") + public static class DigestInstance { + + private static IRubyObject throwUnimplError(IRubyObject self, String name) { + throw self.getRuntime().newRuntimeError(String.format("%s does not implement %s()", self.getMetaClass().getRealClass().getName(), name)); + } + + /* instance methods that should be overridden */ + @JRubyMethod(name = {"update", "<<"}, required = 1) + public static IRubyObject update(ThreadContext context, IRubyObject self, IRubyObject arg) { + return throwUnimplError(self, "update"); + } + + @JRubyMethod() + public static IRubyObject finish(ThreadContext context, IRubyObject self) { + return throwUnimplError(self, "finish"); + } + + @JRubyMethod() + public static IRubyObject reset(ThreadContext context, IRubyObject self) { + return throwUnimplError(self, "reset"); + } + + @JRubyMethod() + public static IRubyObject digest_length(ThreadContext context, IRubyObject self) { + return digest(context, self, null).convertToString().bytesize(); + } + + @JRubyMethod() + public static IRubyObject block_length(ThreadContext context, IRubyObject self) { + return throwUnimplError(self, "block_length"); + } + + /* instance methods that may be overridden */ + @JRubyMethod(name = "==", required = 1) + public static IRubyObject op_equal(ThreadContext context, IRubyObject self, IRubyObject oth) { + if(oth.isNil()) return context.fals; + + RubyString str1, str2; + RubyModule instance = (RubyModule)context.runtime.getModule("Digest").getConstantAt("Instance"); + if (oth.getMetaClass().getRealClass().hasModuleInHierarchy(instance)) { + str1 = digest(context, self, null).convertToString(); + str2 = digest(context, oth, null).convertToString(); + } else { + str1 = to_s(context, self).convertToString(); + str2 = oth.convertToString(); + } + boolean ret = str1.bytesize().eql(str2.bytesize()) && (str1.eql(str2)); + return ret ? context.tru : context.fals; + } + + @JRubyMethod() + public static IRubyObject inspect(ThreadContext context, IRubyObject self) { + return RubyString.newStringNoCopy(self.getRuntime(), ByteList.plain("#<" + self.getMetaClass().getRealClass().getName() + ": " + hexdigest(context, self, null) + ">")); + } + + /* instance methods that need not usually be overridden */ + @JRubyMethod(name = "new") + public static IRubyObject newObject(ThreadContext context, IRubyObject self) { + return self.rbClone().callMethod(context, "reset"); + } + + @JRubyMethod(optional = 1) + public static IRubyObject digest(ThreadContext context, IRubyObject self, IRubyObject[] args) { + final IRubyObject value; + if (args != null && args.length > 0) { + self.callMethod(context, "reset"); + self.callMethod(context, "update", args[0]); + value = self.callMethod(context, "finish"); + self.callMethod(context, "reset"); + } else { + IRubyObject clone = self.rbClone(); + value = clone.callMethod(context, "finish"); + clone.callMethod(context, "reset"); + } + return value; + } + + @JRubyMethod(name = "digest!") + public static IRubyObject digest_bang(ThreadContext context, IRubyObject self) { + IRubyObject value = self.callMethod(context, "finish"); + self.callMethod(context, "reset"); + return value; + } + + @JRubyMethod(optional = 1) + public static IRubyObject hexdigest(ThreadContext context, IRubyObject self, IRubyObject[] args) { + return toHexString(context.runtime, digest(context, self, args).convertToString().getBytes()); + } + + @JRubyMethod(name = "hexdigest!") + public static IRubyObject hexdigest_bang(ThreadContext context, IRubyObject self) { + return toHexString(context.runtime, digest_bang(context, self).convertToString().getBytes()); + } + + @JRubyMethod(name = "bubblebabble", required = 1, optional = 1, meta = true) + public static IRubyObject bubblebabble(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) { + byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes(); + return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length)); + } + + @JRubyMethod() + public static IRubyObject to_s(ThreadContext context, IRubyObject self) { + return self.callMethod(context, "hexdigest"); + } + + @JRubyMethod(name = {"length", "size"}) + public static IRubyObject length(ThreadContext context, IRubyObject self) { + return self.callMethod(context, "digest_length"); + } + } + + + @JRubyClass(name="Digest::Class") + public static class DigestClass extends RubyObject { + public DigestClass(Ruby runtime, RubyClass type) { + super(runtime, type); + } + + @JRubyMethod(name = "digest", required = 1, rest = true, meta = true) + public static IRubyObject s_digest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) { + final Ruby runtime = context.runtime; + if (args.length < 1) { + throw runtime.newArgumentError("no data given"); + } + RubyString str = args[0].convertToString(); + args = ArraySupport.newCopy(args, 1, args.length - 1); // skip first arg + IRubyObject obj = ((RubyClass) recv).newInstance(context, args, Block.NULL_BLOCK); + return obj.callMethod(context, "digest", str); + } + + @JRubyMethod(name = "hexdigest", required = 1, optional = 1, meta = true) + public static IRubyObject s_hexdigest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) { + Ruby runtime = recv.getRuntime(); + byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes(); + return RubyDigest.toHexString(runtime, digest); + } + + @JRubyMethod(name = "bubblebabble", required = 1, meta = true) + public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) { + byte[] digest = recv.callMethod(recv.getRuntime().getCurrentContext(), "digest", arg).convertToString().getBytes(); + return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length)); + } + } + + + @JRubyClass(name="Digest::Base") + public static class DigestBase extends RubyObject { + private MessageDigest algo; + private int blockLength = 0; + + public DigestBase(Ruby runtime, RubyClass type) { + super(runtime,type); + + if(type == runtime.getModule("Digest").getClass("Base")) { + throw runtime.newNotImplementedError("Digest::Base is an abstract class"); + } + + Metadata metadata = getMetadata(type); + if(metadata == null) { + throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine"); + } + + try { + setAlgorithm(metadata); + } catch(NoSuchAlgorithmException e) { + throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine"); + } + + } + + // if subclass extends particular digest we need to walk to find it...we should rearchitect digest to avoid walking type systems + private Metadata getMetadata(RubyModule type) { + for (RubyModule current = type; current != null; current = current.getSuperClass()) { + Metadata metadata = (Metadata) current.getInternalVariable("metadata"); + + if (metadata != null) return metadata; + } + + return null; + } + + @JRubyMethod(required = 1, visibility = Visibility.PRIVATE) + @Override + public IRubyObject initialize_copy(IRubyObject obj) { + if (this == obj) return this; + + DigestBase from = (DigestBase) obj; + from.checkFrozen(); + + try { + this.algo = (MessageDigest) from.algo.clone(); + } + catch (CloneNotSupportedException e) { + String name = from.algo.getAlgorithm(); + throw getRuntime().newTypeError("Could not initialize copy of digest (" + name + ")"); + } + return this; + } + + @JRubyMethod(name = {"update", "<<"}, required = 1) + public IRubyObject update(IRubyObject obj) { + ByteList bytes = obj.convertToString().getByteList(); + algo.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize()); + return this; + } + + @JRubyMethod() + public IRubyObject finish() { + IRubyObject digest = RubyString.newStringNoCopy(getRuntime(), algo.digest()); + algo.reset(); + return digest; + } + + @JRubyMethod() + public IRubyObject digest_length() { + return RubyFixnum.newFixnum(getRuntime(), algo.getDigestLength()); + } + + @JRubyMethod() + public IRubyObject block_length() { + if (blockLength == 0) { + throw getRuntime().newRuntimeError( + this.getMetaClass() + " doesn't implement block_length()"); + } + return RubyFixnum.newFixnum(getRuntime(), blockLength); + } + + @JRubyMethod() + public IRubyObject reset() { + algo.reset(); + return this; + } + + @JRubyMethod() + public IRubyObject bubblebabble(ThreadContext context) { + final byte[] digest = algo.digest(); + return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(digest, 0, digest.length)); + } + + private void setAlgorithm(Metadata metadata) throws NoSuchAlgorithmException { + this.algo = createMessageDigest(metadata.getName()); + this.blockLength = metadata.getBlockLength(); + } + + } +}// RubyDigest diff --git a/ext/java/org/jruby/ext/digest/SHA1.java b/ext/java/org/jruby/ext/digest/SHA1.java new file mode 100644 index 0000000..974eb55 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/SHA1.java @@ -0,0 +1,41 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2010 Charles Oliver Nutter + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.io.IOException; +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; + +public class SHA1 implements Library { + + public void load(final Ruby runtime, boolean wrap) throws IOException { + org.jruby.ext.digest.RubyDigest.createDigestSHA1(runtime); + } +} diff --git a/ext/java/org/jruby/ext/digest/SHA2.java b/ext/java/org/jruby/ext/digest/SHA2.java new file mode 100644 index 0000000..020183d --- /dev/null +++ b/ext/java/org/jruby/ext/digest/SHA2.java @@ -0,0 +1,41 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Eclipse Public + * License Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.eclipse.org/legal/epl-v20.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * Copyright (C) 2010 Charles Oliver Nutter + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the EPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the EPL, the GPL or the LGPL. + ***** END LICENSE BLOCK *****/ + +package org.jruby.ext.digest; + +import java.io.IOException; +import org.jruby.Ruby; +import org.jruby.runtime.load.Library; + +public class SHA2 implements Library { + + public void load(final Ruby runtime, boolean wrap) throws IOException { + org.jruby.ext.digest.RubyDigest.createDigestSHA2(runtime); + } +} diff --git a/test/lib/core_assertions.rb b/test/lib/core_assertions.rb index ff78c2b..928af7b 100644 --- a/test/lib/core_assertions.rb +++ b/test/lib/core_assertions.rb @@ -291,6 +291,7 @@ def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **o eom args = args.dup args.insert((Hash === args.first ? 1 : 0), "-w", "--disable=gems", *$:.map {|l| "-I#{l}"}) + args << "--debug" if RUBY_ENGINE == 'jruby' # warning: tracing (e.g. set_trace_func) will not capture all events without --debug flag stdout, stderr, status = EnvUtil.invoke_ruby(args, src, capture_stdout, true, **opt) ensure if res_c From eaee3a2a67a4278f28585d37c75639944e8e39ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Rosick=C3=BD?= Date: Mon, 14 Jun 2021 21:00:40 +0200 Subject: [PATCH 02/13] allow cross compilation --- Rakefile | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Rakefile b/Rakefile index 4e55a63..8f6084f 100644 --- a/Rakefile +++ b/Rakefile @@ -7,26 +7,24 @@ Rake::TestTask.new(:test) do |t| t.test_files = FileList["test/**/test_*.rb"] end -if RUBY_ENGINE == 'jruby' - require 'rake/javaextensiontask' - Rake::JavaExtensionTask.new("digest") do |ext| - ext.source_version = '1.8' - ext.target_version = '1.8' - ext.ext_dir = 'ext/java' - end +require 'rake/javaextensiontask' +Rake::JavaExtensionTask.new("digest") do |ext| + ext.source_version = '1.8' + ext.target_version = '1.8' + ext.ext_dir = 'ext/java' +end - # copy library loaders - require 'fileutils' - %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| - FileUtils.mkdir "./lib/digest" unless File.exist?("./lib/digest") - FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb" - end -else - require 'rake/extensiontask' - Rake::ExtensionTask.new("digest") - %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| - Rake::ExtensionTask.new("digest/#{ext}") - end +# copy library loaders +require 'fileutils' +%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + FileUtils.mkdir "./lib/digest" unless File.exist?("./lib/digest") + FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb" +end + +require 'rake/extensiontask' +Rake::ExtensionTask.new("digest") +%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + Rake::ExtensionTask.new("digest/#{ext}") end task :sync_tool do From dbd3875b97060162481f11170eb5782c355f656d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Rosick=C3=BD?= Date: Mon, 14 Jun 2021 21:20:33 +0200 Subject: [PATCH 03/13] skip compilation on jruby engine --- Rakefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 8f6084f..9acdb30 100644 --- a/Rakefile +++ b/Rakefile @@ -21,10 +21,12 @@ require 'fileutils' FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb" end -require 'rake/extensiontask' -Rake::ExtensionTask.new("digest") -%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| - Rake::ExtensionTask.new("digest/#{ext}") +if RUBY_ENGINE != 'jruby' + require 'rake/extensiontask' + Rake::ExtensionTask.new("digest") + %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + Rake::ExtensionTask.new("digest/#{ext}") + end end task :sync_tool do From 154d461e914db34f99c46fced5fa6c3ed361b87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Rosick=C3=BD?= Date: Wed, 7 Jul 2021 14:29:57 +0200 Subject: [PATCH 04/13] relicence under the Ruby license and the BSD 2-clause --- README.md | 2 -- digest.gemspec | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index a7ea58e..8b73e9a 100644 --- a/README.md +++ b/README.md @@ -95,5 +95,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/d ## License The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). - -Files under ext/java (JRuby's digest) are licensed under [Eclipse Public License version 2.0](https://opensource.org/licenses/EPL-2.0), [GNU General Public License version 2](https://opensource.org/licenses/GPL-2.0), [GNU Lesser General Public License version 2.1](https://opensource.org/licenses/LGPL-2.1). diff --git a/digest.gemspec b/digest.gemspec index a6c6f15..f9357b0 100644 --- a/digest.gemspec +++ b/digest.gemspec @@ -10,11 +10,7 @@ Gem::Specification.new do |spec| spec.summary = %q{Provides a framework for message digest libraries.} spec.description = %q{Provides a framework for message digest libraries.} spec.homepage = "https://github.com/ruby/digest" - if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' - spec.licenses = ["Ruby", "BSD-2-Clause", "EPL-2.0", "GPL-2.0", "LGPL-2.1"] - else - spec.licenses = ["Ruby", "BSD-2-Clause"] - end + spec.licenses = ["Ruby", "BSD-2-Clause"] spec.files = [ "LICENSE.txt", "README.md", From 11df7f933d4d2e8b46aa43e39e16ab331799ace8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Rosick=C3=BD?= Date: Sun, 5 Sep 2021 23:51:32 +0200 Subject: [PATCH 05/13] update license blocks --- .../org/jruby/ext/digest/BubbleBabble.java | 42 ++++++++-------- .../org/jruby/ext/digest/DigestLibrary.java | 47 +++++++++--------- ext/java/org/jruby/ext/digest/MD5.java | 42 ++++++++-------- ext/java/org/jruby/ext/digest/RMD160.java | 42 ++++++++-------- ext/java/org/jruby/ext/digest/RubyDigest.java | 48 +++++++++---------- ext/java/org/jruby/ext/digest/SHA1.java | 42 ++++++++-------- ext/java/org/jruby/ext/digest/SHA2.java | 42 ++++++++-------- 7 files changed, 153 insertions(+), 152 deletions(-) diff --git a/ext/java/org/jruby/ext/digest/BubbleBabble.java b/ext/java/org/jruby/ext/digest/BubbleBabble.java index 27b457c..a16d165 100644 --- a/ext/java/org/jruby/ext/digest/BubbleBabble.java +++ b/ext/java/org/jruby/ext/digest/BubbleBabble.java @@ -1,30 +1,30 @@ /* **** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (c) 2010, Charles Oliver Nutter + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2010 Charles Oliver Nutter + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/DigestLibrary.java b/ext/java/org/jruby/ext/digest/DigestLibrary.java index 00f15bf..cd46954 100644 --- a/ext/java/org/jruby/ext/digest/DigestLibrary.java +++ b/ext/java/org/jruby/ext/digest/DigestLibrary.java @@ -1,29 +1,30 @@ -/***** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 +/* + **** BEGIN LICENSE BLOCK ***** + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (C) 2006 Ola Bini + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2006 Ola Bini - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/MD5.java b/ext/java/org/jruby/ext/digest/MD5.java index 65b6821..124d053 100644 --- a/ext/java/org/jruby/ext/digest/MD5.java +++ b/ext/java/org/jruby/ext/digest/MD5.java @@ -1,30 +1,30 @@ /* **** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (c) 2010, Charles Oliver Nutter + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2010 Charles Oliver Nutter + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/RMD160.java b/ext/java/org/jruby/ext/digest/RMD160.java index abe675c..94b17ed 100644 --- a/ext/java/org/jruby/ext/digest/RMD160.java +++ b/ext/java/org/jruby/ext/digest/RMD160.java @@ -1,30 +1,30 @@ /* **** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (c) 2010, Charles Oliver Nutter + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2010 Charles Oliver Nutter + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/RubyDigest.java b/ext/java/org/jruby/ext/digest/RubyDigest.java index e60bfca..f10b8ca 100644 --- a/ext/java/org/jruby/ext/digest/RubyDigest.java +++ b/ext/java/org/jruby/ext/digest/RubyDigest.java @@ -1,33 +1,33 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + /* + **** BEGIN LICENSE BLOCK ***** + * BSD 2-Clause License * * Copyright (C) 2006, 2007 Ola Bini * Copyright (C) 2007 Nick Sieger * Copyright (C) 2008 Vladimir Sizikov * Copyright (C) 2009 Joseph LaFata + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/SHA1.java b/ext/java/org/jruby/ext/digest/SHA1.java index 974eb55..f2a0043 100644 --- a/ext/java/org/jruby/ext/digest/SHA1.java +++ b/ext/java/org/jruby/ext/digest/SHA1.java @@ -1,30 +1,30 @@ /* **** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (c) 2010, Charles Oliver Nutter + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2010 Charles Oliver Nutter + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; diff --git a/ext/java/org/jruby/ext/digest/SHA2.java b/ext/java/org/jruby/ext/digest/SHA2.java index 020183d..f9e58e3 100644 --- a/ext/java/org/jruby/ext/digest/SHA2.java +++ b/ext/java/org/jruby/ext/digest/SHA2.java @@ -1,30 +1,30 @@ /* **** BEGIN LICENSE BLOCK ***** - * Version: EPL 2.0/GPL 2.0/LGPL 2.1 + * BSD 2-Clause License * - * The contents of this file are subject to the Eclipse Public - * License Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.eclipse.org/legal/epl-v20.html + * Copyright (c) 2010, Charles Oliver Nutter + * All rights reserved. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright (C) 2010 Charles Oliver Nutter + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the EPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the EPL, the GPL or the LGPL. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***** END LICENSE BLOCK *****/ package org.jruby.ext.digest; From c614c31ef9624d5ca753434676b4c2e33bb01dca Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Mon, 27 Sep 2021 16:30:31 +0900 Subject: [PATCH 06/13] Fix the location of core_assertions.rb --- Rakefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 9acdb30..e367f8a 100644 --- a/Rakefile +++ b/Rakefile @@ -30,10 +30,9 @@ if RUBY_ENGINE != 'jruby' end task :sync_tool do - require 'fileutils' - FileUtils.cp "../ruby/tool/lib/test/unit/core_assertions.rb", "./test/lib" - FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib" - FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib" + cp "../ruby/tool/lib/core_assertions.rb", "./test/lib" + cp "../ruby/tool/lib/envutil.rb", "./test/lib" + cp "../ruby/tool/lib/find_executable.rb", "./test/lib" end task :default => :test From 8d7496c3be3b3476510d92a40443965102398da5 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Mon, 27 Sep 2021 16:31:55 +0900 Subject: [PATCH 07/13] Place common parts in lib and engine specific parts under ext/**/lib --- .gitignore | 2 - Rakefile | 32 +++++------ digest.gemspec | 55 ++++--------------- ext/digest/bubblebabble/lib/bubblebabble.rb | 9 --- ext/digest/lib/digest/loader.rb | 3 + ext/digest/lib/digest/sha2/loader.rb | 3 + ext/digest/md5/lib/md5.rb | 9 --- ext/digest/rmd160/lib/rmd160.rb | 9 --- ext/digest/sha1/lib/sha1.rb | 9 --- .../ext/digest/lib/digest/bubblebabble.rb | 3 + .../org/jruby/ext/digest/lib/digest/loader.rb | 3 + .../org/jruby/ext/digest/lib/digest/md5.rb | 3 + .../org/jruby/ext/digest/lib/digest/rmd160.rb | 3 + .../org/jruby/ext/digest/lib/digest/sha1.rb | 3 + .../ext/digest/lib/digest/sha2/loader.rb | 3 + {ext/digest/lib => lib}/digest.rb | 7 +-- {ext/digest/sha2/lib => lib/digest}/sha2.rb | 7 +-- 17 files changed, 53 insertions(+), 110 deletions(-) delete mode 100644 ext/digest/bubblebabble/lib/bubblebabble.rb create mode 100644 ext/digest/lib/digest/loader.rb create mode 100644 ext/digest/lib/digest/sha2/loader.rb delete mode 100644 ext/digest/md5/lib/md5.rb delete mode 100644 ext/digest/rmd160/lib/rmd160.rb delete mode 100644 ext/digest/sha1/lib/sha1.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/loader.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/md5.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/sha1.rb create mode 100644 ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb rename {ext/digest/lib => lib}/digest.rb (96%) rename {ext/digest/sha2/lib => lib/digest}/sha2.rb (97%) diff --git a/.gitignore b/.gitignore index 3e810e4..e8f02c7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,6 @@ /spec/reports/ /tmp/ lib/*.jar -lib/digest -lib/digest/*.rb *.bundle *.so *.o diff --git a/Rakefile b/Rakefile index e367f8a..150ceb4 100644 --- a/Rakefile +++ b/Rakefile @@ -3,28 +3,26 @@ require "rake/testtask" Rake::TestTask.new(:test) do |t| t.libs << "test" << "test/lib" << "lib" + if RUBY_ENGINE == "jruby" + t.libs << "ext/java/org/jruby/ext/digest/lib" + else + t.libs << "ext/digest/lib" + end t.ruby_opts << "-rhelper" t.test_files = FileList["test/**/test_*.rb"] end -require 'rake/javaextensiontask' -Rake::JavaExtensionTask.new("digest") do |ext| - ext.source_version = '1.8' - ext.target_version = '1.8' - ext.ext_dir = 'ext/java' -end - -# copy library loaders -require 'fileutils' -%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| - FileUtils.mkdir "./lib/digest" unless File.exist?("./lib/digest") - FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb" -end - -if RUBY_ENGINE != 'jruby' - require 'rake/extensiontask' +if RUBY_ENGINE == "jruby" + require "rake/javaextensiontask" + Rake::JavaExtensionTask.new("digest") do |ext| + ext.source_version = "1.8" + ext.target_version = "1.8" + ext.ext_dir = "ext/java" + end +else + require "rake/extensiontask" Rake::ExtensionTask.new("digest") - %w(bubblebabble md5 rmd160 sha1 sha2).each do |ext| + %w[bubblebabble md5 rmd160 sha1 sha2].each do |ext| Rake::ExtensionTask.new("digest/#{ext}") end end diff --git a/digest.gemspec b/digest.gemspec index f9357b0..151d160 100644 --- a/digest.gemspec +++ b/digest.gemspec @@ -12,60 +12,27 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/ruby/digest" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.files = [ - "LICENSE.txt", "README.md", - - "ext/digest/defs.h", "ext/digest/digest.c", "ext/digest/digest.h", - "ext/digest/digest_conf.rb", "ext/digest/extconf.rb", - "ext/digest/lib/digest.rb", - - "ext/digest/bubblebabble/bubblebabble.c", - "ext/digest/bubblebabble/extconf.rb", - - "ext/digest/md5/extconf.rb", "ext/digest/md5/md5.c", - "ext/digest/md5/md5.h", "ext/digest/md5/md5cc.h", - "ext/digest/md5/md5init.c", - - "ext/digest/rmd160/extconf.rb", "ext/digest/rmd160/rmd160.c", - "ext/digest/rmd160/rmd160.h", "ext/digest/rmd160/rmd160init.c", - - "ext/digest/sha1/extconf.rb", "ext/digest/sha1/sha1.c", - "ext/digest/sha1/sha1.h", "ext/digest/sha1/sha1cc.h", - "ext/digest/sha1/sha1init.c", - - "ext/digest/sha2/extconf.rb", "ext/digest/sha2/lib/sha2.rb", - "ext/digest/sha2/sha2.c", "ext/digest/sha2/sha2.h", - "ext/digest/sha2/sha2cc.h", "ext/digest/sha2/sha2init.c", - - "ext/openssl/deprecation.rb", - "ext/digest/test.sh", + spec.files = [ + "LICENSE.txt", + "README.md", + *Dir["lib/digest{.rb,/**/*.rb}"], ] spec.required_ruby_version = ">= 2.5.0" spec.bindir = "exe" spec.executables = [] - spec.require_paths = ["lib"] if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' spec.platform = 'java' - spec.files.concat [ - "lib/digest.jar", - "lib/digest/md5.rb", - "lib/digest/sha1.rb", - "lib/digest/sha2.rb", - "lib/digest/rmd160.rb", - "lib/digest/bubblebabble.rb" - ] + + spec.files += Dir["ext/java/**/*.{rb,java}"] + spec.require_paths = %w[lib ext/java/org/jruby/ext/digest/lib] else - spec.extensions = %w[ - ext/digest/extconf.rb - ext/digest/bubblebabble/extconf.rb - ext/digest/md5/extconf.rb - ext/digest/rmd160/extconf.rb - ext/digest/sha1/extconf.rb - ext/digest/sha2/extconf.rb - ] + spec.extensions = Dir["ext/digest/**/extconf.rb"] + + spec.files += Dir["ext/digest/**/*.{rb,c,h,sh}"] + spec.require_paths = %w[lib] end spec.metadata["msys2_mingw_dependencies"] = "openssl" diff --git a/ext/digest/bubblebabble/lib/bubblebabble.rb b/ext/digest/bubblebabble/lib/bubblebabble.rb deleted file mode 100644 index 8ad06c7..0000000 --- a/ext/digest/bubblebabble/lib/bubblebabble.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false - -require 'digest' - -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.BubbleBabble") -else - require 'digest/bubblebabble.so' -end diff --git a/ext/digest/lib/digest/loader.rb b/ext/digest/lib/digest/loader.rb new file mode 100644 index 0000000..6b989e0 --- /dev/null +++ b/ext/digest/lib/digest/loader.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require 'digest.so' diff --git a/ext/digest/lib/digest/sha2/loader.rb b/ext/digest/lib/digest/sha2/loader.rb new file mode 100644 index 0000000..7d6d04a --- /dev/null +++ b/ext/digest/lib/digest/sha2/loader.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require 'digest/sha2.so' diff --git a/ext/digest/md5/lib/md5.rb b/ext/digest/md5/lib/md5.rb deleted file mode 100644 index 3748f9d..0000000 --- a/ext/digest/md5/lib/md5.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false - -require 'digest' - -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.MD5") -else - require 'digest/md5.so' -end diff --git a/ext/digest/rmd160/lib/rmd160.rb b/ext/digest/rmd160/lib/rmd160.rb deleted file mode 100644 index eabb92a..0000000 --- a/ext/digest/rmd160/lib/rmd160.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false - -require 'digest' - -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.RMD160") -else - require 'digest/rmd160.so' -end diff --git a/ext/digest/sha1/lib/sha1.rb b/ext/digest/sha1/lib/sha1.rb deleted file mode 100644 index 864997b..0000000 --- a/ext/digest/sha1/lib/sha1.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false - -require 'digest' - -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.SHA1") -else - require 'digest/sha1.so' -end diff --git a/ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb b/ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb new file mode 100644 index 0000000..011eab2 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext("org.jruby.ext.digest.BubbleBabble") diff --git a/ext/java/org/jruby/ext/digest/lib/digest/loader.rb b/ext/java/org/jruby/ext/digest/lib/digest/loader.rb new file mode 100644 index 0000000..5661dbd --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/loader.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext('org.jruby.ext.digest.DigestLibrary') diff --git a/ext/java/org/jruby/ext/digest/lib/digest/md5.rb b/ext/java/org/jruby/ext/digest/lib/digest/md5.rb new file mode 100644 index 0000000..f76ffb2 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/md5.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext("org.jruby.ext.digest.MD5") diff --git a/ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb b/ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb new file mode 100644 index 0000000..4b22d10 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext("org.jruby.ext.digest.RMD160") diff --git a/ext/java/org/jruby/ext/digest/lib/digest/sha1.rb b/ext/java/org/jruby/ext/digest/lib/digest/sha1.rb new file mode 100644 index 0000000..6bcb434 --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/sha1.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext("org.jruby.ext.digest.SHA1") diff --git a/ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb b/ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb new file mode 100644 index 0000000..746236a --- /dev/null +++ b/ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +JRuby::Util.load_ext('org.jruby.ext.digest.SHA2') diff --git a/ext/digest/lib/digest.rb b/lib/digest.rb similarity index 96% rename from ext/digest/lib/digest.rb rename to lib/digest.rb index 9121988..b5ff067 100644 --- a/ext/digest/lib/digest.rb +++ b/lib/digest.rb @@ -1,9 +1,6 @@ # frozen_string_literal: false -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.DigestLibrary") -else - require 'digest.so' -end + +require 'digest/loader' module Digest # A mutex for Digest(). diff --git a/ext/digest/sha2/lib/sha2.rb b/lib/digest/sha2.rb similarity index 97% rename from ext/digest/sha2/lib/sha2.rb rename to lib/digest/sha2.rb index 22e0997..f17593a 100644 --- a/ext/digest/sha2/lib/sha2.rb +++ b/lib/digest/sha2.rb @@ -11,12 +11,7 @@ # $Id$ require 'digest' - -if RUBY_ENGINE == 'jruby' - JRuby::Util.load_ext("org.jruby.ext.digest.SHA2") -else - require 'digest/sha2.so' -end +require 'digest/sha2/loader' module Digest # From 042d010f5a2a2b231bb002dd3d69532dfcbe762a Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Mon, 27 Sep 2021 16:35:55 +0900 Subject: [PATCH 08/13] Run rake with bundle exec --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbae97b..24d9d89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,11 +44,11 @@ jobs: - run: bundle install - - run: rake compile + - run: bundle exec rake compile - - run: rake build + - run: bundle exec rake build - - run: rake test + - run: bundle exec rake test - run: gem install pkg/*.gem continue-on-error: ${{ matrix.ignore-pkg-error || (matrix.ruby == 'debug') }} From 1747f49cfe63dcba8e38c655539958729dbc7c79 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Tue, 28 Sep 2021 00:19:01 +0900 Subject: [PATCH 09/13] Drop Ruby 2.5 which reached EOL 6 months ago --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24d9d89..ed65462 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,6 @@ jobs: - '3.0' - 2.7 - 2.6 - - 2.5 - debug include: - { os: ubuntu-20.04, ruby: head, ignore-pkg-error: true } From b300ba3c75098ad55db042bc5678a584d0c3d5f2 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Tue, 28 Sep 2021 17:01:46 +0900 Subject: [PATCH 10/13] Add gem installation check --- .github/workflows/ci.yml | 2 +- Rakefile | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed65462..349aec7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,5 +49,5 @@ jobs: - run: bundle exec rake test - - run: gem install pkg/*.gem + - run: rake check continue-on-error: ${{ matrix.ignore-pkg-error || (matrix.ruby == 'debug') }} diff --git a/Rakefile b/Rakefile index 150ceb4..87d5580 100644 --- a/Rakefile +++ b/Rakefile @@ -33,4 +33,41 @@ task :sync_tool do cp "../ruby/tool/lib/find_executable.rb", "./test/lib" end +task :check => :"install:local" do + spec = Gem::Specification::load("digest.gemspec") + version = spec.version.to_s + + require_relative "test/lib/envutil" + + _, _, status = EnvUtil.invoke_ruby([], <<~EOS) + version = #{version.dump} + gem "digest", version + loaded_version = Gem.loaded_specs["digest"].version.to_s + + if loaded_version == version + puts "digest \#{loaded_version} is loaded." + else + abort "digest \#{loaded_version} is loaded instead of \#{version}!" + end + + require "digest" + + string = "digest" + actual = Digest::SHA256.hexdigest(string) + expected = "0bf474896363505e5ea5e5d6ace8ebfb13a760a409b1fb467d428fc716f9f284" + puts "sha256(\#{string.dump}) = \#{actual.dump}" + + if actual != expected + abort "no! expected to be \#{expected.dump}!" + end + EOS + + if status.success? + puts "check succeeded!" + else + warn "check failed!" + exit status.exitstatus + end +end + task :default => :test From b602feef00a12d7613f729a20abbd6eae92d35a6 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Tue, 28 Sep 2021 21:37:06 +0900 Subject: [PATCH 11/13] Use macos-11 instead of macos-11.0 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 349aec7..e802b91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: os: - ubuntu-20.04 - ubuntu-18.04 - - macos-11.0 + - macos-11 - macos-10.15 - windows-latest ruby: From bcb852e848f05f3db0cef860b4ec7e1c80a4fea2 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Tue, 28 Sep 2021 21:37:54 +0900 Subject: [PATCH 12/13] Test with `jruby` with package check enabled --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e802b91..32bd073 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: - { os: ubuntu-20.04, ruby: head, ignore-pkg-error: true } - { os: windows-latest, ruby: mingw, ignore-pkg-error: true } - { os: windows-latest, ruby: mswin, ignore-pkg-error: true } + - { os: ubuntu-20.04, ruby: jruby } - { os: ubuntu-20.04, ruby: jruby-head, ignore-pkg-error: true } exclude: - { os: windows-latest, ruby: debug } From 2855e3e997ff0690404b4225dc12de626128e7dd Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Wed, 29 Sep 2021 01:47:11 +0900 Subject: [PATCH 13/13] Delete ext/openssl that has no use --- ext/openssl/deprecation.rb | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 ext/openssl/deprecation.rb diff --git a/ext/openssl/deprecation.rb b/ext/openssl/deprecation.rb deleted file mode 100644 index 1d51d06..0000000 --- a/ext/openssl/deprecation.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: false -module OpenSSL - def self.deprecated_warning_flag - unless flag = (@deprecated_warning_flag ||= nil) - if try_compile("", flag = "-Werror=deprecated-declarations") - $warnflags << " #{flag}" - else - flag = "" - end - @deprecated_warning_flag = flag - end - flag - end - - def self.check_func(func, header) - have_func(func, header, deprecated_warning_flag) - end - - def self.check_func_or_macro(func, header) - check_func(func, header) or - have_macro(func, header) && $defs.push("-DHAVE_#{func.upcase}") - end -end