From 3fe2f2689f0074a4c880218ca08cb10137880760 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Tue, 24 Oct 2023 11:18:04 -0500 Subject: [PATCH] [rubygems/rubygems] Raise exception on unexpected EOF in marshal Instead of NoMethodError being raised by accidentally trying to use nil https://github.com/rubygems/rubygems/commit/ac8f812bbf --- lib/rubygems/safe_marshal/reader.rb | 7 +++++++ test/rubygems/test_gem_safe_marshal.rb | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/rubygems/safe_marshal/reader.rb b/lib/rubygems/safe_marshal/reader.rb index c2c2295086..7c3a703475 100644 --- a/lib/rubygems/safe_marshal/reader.rb +++ b/lib/rubygems/safe_marshal/reader.rb @@ -17,6 +17,9 @@ module Gem class NotImplementedError < Error end + class EOFError < Error + end + def initialize(io) @io = io end @@ -64,6 +67,8 @@ module Gem read_byte | (read_byte << 8) | -0x10000 when 0xFF read_byte | -0x100 + when nil + raise EOFError, "Unexpected EOF" else signed = (b ^ 128) - 128 if b >= 128 @@ -102,6 +107,8 @@ module Gem when 47 then read_regexp # ?/ when 83 then read_struct # ?S when 67 then read_user_class # ?C + when nil + raise EOFError, "Unexpected EOF" else raise Error, "Unknown marshal type discriminator #{type.chr.inspect} (#{type})" end diff --git a/test/rubygems/test_gem_safe_marshal.rb b/test/rubygems/test_gem_safe_marshal.rb index dc7ce362c4..362e5e00ad 100644 --- a/test/rubygems/test_gem_safe_marshal.rb +++ b/test/rubygems/test_gem_safe_marshal.rb @@ -310,6 +310,23 @@ class TestGemSafeMarshal < Gem::TestCase assert_equal e.message, "Attempting to set unpermitted ivar \"@foobar\" on object of class Hash @ root.[18].ivar_0" end + def test_unexpected_eof + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08") + end + assert_equal e.message, "Unexpected EOF" + + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08[") + end + assert_equal e.message, "Unexpected EOF" + + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08[\x06") + end + assert_equal e.message, "Unexpected EOF" + end + def assert_safe_load_marshal(dumped, additional_methods: [], permitted_ivars: nil, equality: true, marshal_dump_equality: true) loaded = Marshal.load(dumped) safe_loaded =