From cf67782e4391367ada28e07cff56a410939292b5 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 5 Jul 2023 13:56:05 +0200 Subject: [PATCH] Fix AS::Cache 7.1 format to properly compress bare strings The bare string and compression features weren't working properly together. I discovered this while trying to fix deprecation warnings. --- .../cache/serializer_with_fallback.rb | 19 +++++++++++++++---- activesupport/test/abstract_unit.rb | 2 ++ .../cache_store_format_version_behavior.rb | 19 +++++++++++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/activesupport/lib/active_support/cache/serializer_with_fallback.rb b/activesupport/lib/active_support/cache/serializer_with_fallback.rb index 196d037f8c77d..260d82ce317c5 100644 --- a/activesupport/lib/active_support/cache/serializer_with_fallback.rb +++ b/activesupport/lib/active_support/cache/serializer_with_fallback.rb @@ -159,12 +159,20 @@ module Marshal71WithFallback MARK_UNCOMPRESSED = "\x00".b.freeze MARK_COMPRESSED = "\x01".b.freeze + def dump(entry, raw = false) + if raw + super(entry) + else + MARK_UNCOMPRESSED + super(entry) + end + end + def _dump(entry) - MARK_UNCOMPRESSED + Marshal.dump(entry.pack) + Marshal.dump(entry.pack) end def dump_compressed(entry, threshold) - dumped = Marshal.dump(entry.pack) + dumped = dump(entry, true) if compressed = try_compress(dumped, threshold) MARK_COMPRESSED + compressed else @@ -175,7 +183,7 @@ def dump_compressed(entry, threshold) def _load(marked) dumped = marked.byteslice(1..-1) dumped = decompress(dumped) if marked.start_with?(MARK_COMPRESSED) - Cache::Entry.unpack(Marshal.load(dumped)) + try_load_bare_string(dumped) || Cache::Entry.unpack(Marshal.load(dumped)) end def dumped?(dumped) @@ -186,7 +194,10 @@ def dumped?(dumped) module Marshal70WithFallback include Marshal71WithFallback extend self - alias :dump :_dump # Prevent dumping bare strings. + + def try_dump_bare_string(_entry) + nil # Prevent dumping bare strings. + end end module MessagePackWithFallback diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 4ef4650ef44cd..a0b153017471a 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -29,6 +29,8 @@ ActiveSupport.to_time_preserves_timezone = ENV.fetch("PRESERVE_TIMEZONES", "1") == "1" end +ActiveSupport::Cache.format_version = 7.1 + # Disable available locale checks to avoid warnings running the test suite. I18n.enforce_available_locales = false diff --git a/activesupport/test/cache/behaviors/cache_store_format_version_behavior.rb b/activesupport/test/cache/behaviors/cache_store_format_version_behavior.rb index add2b8cb2d460..452a4e10f947f 100644 --- a/activesupport/test/cache/behaviors/cache_store_format_version_behavior.rb +++ b/activesupport/test/cache/behaviors/cache_store_format_version_behavior.rb @@ -10,7 +10,7 @@ module CacheStoreFormatVersionBehavior included do test "format version affects default coder" do coders = FORMAT_VERSIONS.map do |format_version| - ActiveSupport::Cache.with(format_version: format_version) do + with_format(format_version) do lookup_store.instance_variable_get(:@coder) end end @@ -19,7 +19,7 @@ module CacheStoreFormatVersionBehavior end test "invalid format version raises" do - ActiveSupport::Cache.with(format_version: 0) do + with_format(0) do assert_raises do lookup_store end @@ -30,11 +30,11 @@ module CacheStoreFormatVersionBehavior test "format version #{read_version.inspect} can read #{write_version.inspect} entries" do key = SecureRandom.uuid - ActiveSupport::Cache.with(format_version: write_version) do + with_format(write_version) do lookup_store.write(key, "value for #{key}") end - ActiveSupport::Cache.with(format_version: read_version) do + with_format(read_version) do assert_equal "value for #{key}", lookup_store.read(key) end end @@ -42,14 +42,21 @@ module CacheStoreFormatVersionBehavior test "format version #{read_version.inspect} can read #{write_version.inspect} entries with compression" do key = SecureRandom.uuid - ActiveSupport::Cache.with(format_version: write_version) do + with_format(write_version) do lookup_store(compress_threshold: 1).write(key, key * 10) end - ActiveSupport::Cache.with(format_version: read_version) do + with_format(read_version) do assert_equal key * 10, lookup_store.read(key) end end end end + + private + def with_format(format_version, &block) + ActiveSupport.deprecator.silence do + ActiveSupport::Cache.with(format_version: format_version, &block) + end + end end