From 8267c375d4de360b8d9318c1be4ec2858d2610db Mon Sep 17 00:00:00 2001 From: Daniel Vu Date: Wed, 24 Jun 2026 22:11:45 -0400 Subject: [PATCH] Ruby 3.3 compat: register DATA scheme via public API; drop URI.decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit data_uri 0.1.0 (the latest published release) breaks on Ruby 3.x: * `@@schemes['DATA'] = Data` — URI's @@schemes class variable was removed. Use URI.register_scheme (public API since Ruby 2.7), guarded for older Ruby. * `URI.decode(@data)` — URI.decode was removed in Ruby 3.0. Use URI::DEFAULT_PARSER.unescape, which does the same RFC-2396 percent-decoding. Also bump the gemspec version 0.0.3 -> 0.1.0 (master's source equals the 0.1.0 release) and drop the removed s.has_rdoc=. Kept 2.7-compatible. --- data_uri.gemspec | 7 +++++-- lib/data_uri/uri.rb | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/data_uri.gemspec b/data_uri.gemspec index c2435ab..056cd84 100644 --- a/data_uri.gemspec +++ b/data_uri.gemspec @@ -1,6 +1,8 @@ Gem::Specification.new do |s| s.name = "data_uri" - s.version = "0.0.3" + # Master's gemspec was left at 0.0.3 though RubyGems published 0.1.0 from the + # identical source. Track 0.1.0 so this fork is a drop-in for the pinned release. + s.version = "0.1.0" s.author = "Donald Ball" s.email = "donald.ball@gmail.com" s.homepage = "http://github.com/dball/data_uri" @@ -8,7 +10,8 @@ Gem::Specification.new do |s| s.summary = "A URI class for parsing data URIs as per RFC2397" s.platform = Gem::Platform::RUBY - s.has_rdoc = true + # s.has_rdoc was removed from RubyGems::Specification; dropping it avoids a + # NoMethodError when the gemspec is evaluated on modern RubyGems. s.extra_rdoc_files = ["README.rdoc"] s.require_path = 'lib' diff --git a/lib/data_uri/uri.rb b/lib/data_uri/uri.rb index 47cfa9e..93ec3d5 100644 --- a/lib/data_uri/uri.rb +++ b/lib/data_uri/uri.rb @@ -37,7 +37,9 @@ def initialize(*args) raise URI::InvalidURIError.new('Invalid data URI') end @data = @data[1 .. -1] - @data = base64 ? Base64.decode64(@data) : URI.decode(@data) + # URI.decode was removed in Ruby 3.0; use the default parser's #unescape, + # which performs the same RFC-2396 percent-decoding the data URI body needs. + @data = base64 ? Base64.decode64(@data) : URI::DEFAULT_PARSER.unescape(@data) if @data.respond_to?(:force_encoding) && charset = @mime_params['charset'] @data.force_encoding(charset) end @@ -61,6 +63,13 @@ def self.build(arg) end end - @@schemes['DATA'] = Data + # Ruby 3.x removed the URI @@schemes class variable. Register via the public + # API (URI.register_scheme, available since Ruby 2.7) instead of mutating the + # internal @@schemes hash directly. + if URI.respond_to?(:register_scheme) + URI.register_scheme('DATA', Data) + else + @@schemes['DATA'] = Data + end end