diff --git a/LICENSE.txt b/LICENSE.txt index 04303bd..cb6bbdf 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2013-2022 Josh Holtrop +Copyright (c) 2013-2025 Josh Holtrop MIT License diff --git a/Rakefile.rb b/Rakefile.rb index 9896808..905eccb 100644 --- a/Rakefile.rb +++ b/Rakefile.rb @@ -32,11 +32,12 @@ end # useful for coverage information. desc "Dist Specs" task :dspec, [:example_string] => :build_dist do |task, args| + FileUtils.rm_rf("test") FileUtils.mkdir_p("test") FileUtils.cp("dist/rscons", "test/rscons.rb") - ENV["dist_specs"] = "1" + ENV["rscons_dist_specs"] = "1" Rake::Task["spec"].execute(args) - ENV.delete("dist_specs") + ENV.delete("rscons_dist_specs") FileUtils.rm_f(Dir.glob(".rscons-*")) end diff --git a/rb/build_dist.rb b/rb/build_dist.rb index b79a68c..96776c3 100755 --- a/rb/build_dist.rb +++ b/rb/build_dist.rb @@ -1,7 +1,10 @@ #!/usr/bin/env ruby -require "fileutils" +require "base64" require "digest/md5" +require "fileutils" +require "stringio" +require "zlib" if File.read("lib/rscons/version.rb") =~ /VERSION = "(.+)"/ VERSION = $1 @@ -68,11 +71,15 @@ license = File.read("LICENSE.txt").gsub(/^(.*?)$/) do |line| end end -require "zlib" -require "base64" compressed_script = Zlib::Deflate.deflate(stripped.join) +hash = Digest::MD5.hexdigest(compressed_script) encoded_compressed_script = Base64.encode64(compressed_script).gsub("\n", "") -hash = Digest::MD5.hexdigest(encoded_compressed_script) +encoded_compressed_script_io = StringIO.new(encoded_compressed_script) +commented_encoded_compressed_script = "" +until encoded_compressed_script_io.eof? + line = encoded_compressed_script_io.read(64) + commented_encoded_compressed_script += "##{line}\n" +end FileUtils.rm_rf(DIST) FileUtils.mkdir_p(DIST) @@ -82,25 +89,53 @@ File.open("#{DIST}/#{PROG_NAME}", "wb", 0755) do |fh| #{license} +BASE64CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +def base64_decode(s) + out = "" + v = 0 + bits = 0 + s.each_char do |c| + if cv = BASE64CHARS.index(c) + v = (v << 6) | cv + bits += 6 + elsif c == "=" + break + end + if bits >= 8 + out += (v >> (bits - 8)).chr + v &= 0xFFFFFFFF >> (32 - (bits - 8)) + bits -= 8 + end + end + out +end + script = File.join(File.dirname(__FILE__), ".rscons-#{VERSION}-#{hash}.rb") unless File.exist?(script) - if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/ + if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/m require "zlib" - require "base64" encoded_compressed = $1 - unescaped_compressed = Base64.decode64(encoded_compressed) - inflated = Zlib::Inflate.inflate(unescaped_compressed) + compressed = base64_decode(encoded_compressed) + if ENV["rscons_dist_specs"] + require "digest/md5" + if Digest::MD5.hexdigest(compressed) != "#{hash}" + raise "Hash mismatch when decompressing rscons executable" + end + end + inflated = Zlib::Inflate.inflate(compressed) File.open(script, "wb") do |fh| fh.write(inflated) end else - raise "Could not decompress." + raise "Error expanding rscons executable" end end load script if __FILE__ == $0 Rscons::Cli.new.run(ARGV) end -#==>#{encoded_compressed_script} +#==> +#{commented_encoded_compressed_script} EOF end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2fc400c..b2ef5fe 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -if ENV["dist_specs"] +if ENV["rscons_dist_specs"] require_relative "../test/rscons" else require "simplecov" @@ -11,12 +11,7 @@ else else command_name "RSpec" end - if ENV["dist_specs"] - add_filter "/bin/" - add_filter "/lib/" - else - add_filter "test/rscons.rb" - end + add_filter "test/rscons.rb" project_name "Rscons" merge_timeout 3600 end