dalli 5.3.1 → 5.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/dalli/compressor.rb +52 -15
- data/lib/dalli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01e6a1f1483a28b5913847f35280e7c4cf2f490f01ddda3607ba1cf7687e3081
|
|
4
|
+
data.tar.gz: 0a4c8e31094f2d0fabc9a17062765d7e5293ec29ed338fabca6c93076d4ea224
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fa29fe92cc42e648f5752c79a185466e24614283d0ebed7f8a12a5b3ab2f98806065c1989c403144b10809ad33baaa4033c66f140e80500c4ecb9c3a6b6a41b
|
|
7
|
+
data.tar.gz: be9a46942962a98dc2d14d9058f48c0b78c22c245b447e7578b030aa941e286a67941516e0d8a9d377167fd9fcbb3960865c3c118e2f3e8ba88ba1aece683914
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ Dalli Changelog
|
|
|
4
4
|
Unreleased
|
|
5
5
|
==========
|
|
6
6
|
|
|
7
|
+
5.3.2
|
|
8
|
+
==========
|
|
9
|
+
|
|
10
|
+
Bug fixes:
|
|
11
|
+
|
|
12
|
+
- A signal arriving while `Dalli::Compressor` or `Dalli::GzipCompressor` was compressing or decompressing could make Ruby's zlib return before it had finished (ruby/zlib#49). Depending on the Ruby and zlib gem versions, that raised `Zlib::BufError` or `Zlib::DataError`, or stored a truncated value that later failed to decompress. Both compressors now keep finishing the stream until zlib reports its end. `GzipCompressor` no longer goes through `GzipWriter` and `GzipReader`, so it now always returns decompressed values as binary strings, as `Compressor` does (#1299)
|
|
13
|
+
|
|
7
14
|
5.3.1
|
|
8
15
|
==========
|
|
9
16
|
|
data/lib/dalli/compressor.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'zlib'
|
|
4
|
-
require 'stringio'
|
|
5
4
|
|
|
6
5
|
module Dalli
|
|
7
6
|
##
|
|
@@ -10,7 +9,7 @@ module Dalli
|
|
|
10
9
|
##
|
|
11
10
|
class Compressor
|
|
12
11
|
def self.compress(data)
|
|
13
|
-
Zlib::Deflate.
|
|
12
|
+
deflate_fully(Zlib::Deflate.new, data)
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
# DEFLATE can't expand data by more than about 1032:1
|
|
@@ -24,11 +23,51 @@ module Dalli
|
|
|
24
23
|
# as the output passes it, so a small compressed value can't expand into
|
|
25
24
|
# gigabytes of memory.
|
|
26
25
|
def self.decompress(data, max_bytes: nil)
|
|
27
|
-
return Zlib::Inflate.
|
|
26
|
+
return inflate_fully(Zlib::Inflate.new, data) unless may_exceed?(data, max_bytes)
|
|
28
27
|
|
|
29
28
|
inflate_within_limit(Zlib::Inflate.new, data, max_bytes)
|
|
30
29
|
end
|
|
31
30
|
|
|
31
|
+
# Ruby's zlib extension can return from a call before zlib has finished
|
|
32
|
+
# when a signal interrupts it (ruby/zlib#49). One-shot calls like
|
|
33
|
+
# Zlib::Deflate.deflate then raise or, with zlib 3.2.4, return truncated
|
|
34
|
+
# output, so these call finish until the stream has ended.
|
|
35
|
+
def self.deflate_fully(deflater, data)
|
|
36
|
+
finish_stream(deflater, deflater.deflate(data, Zlib::FINISH))
|
|
37
|
+
ensure
|
|
38
|
+
deflater.close
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.inflate_fully(inflater, data)
|
|
42
|
+
finish_stream(inflater, feed(inflater, data) || String.new(encoding: Encoding::BINARY))
|
|
43
|
+
ensure
|
|
44
|
+
inflater.close
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# zlib gem 3.2.3 and earlier retry an interrupted inflate even when it has
|
|
48
|
+
# used up its input, and raise the Z_BUF_ERROR zlib returns for that. The
|
|
49
|
+
# output so far stays in the stream, and finish raises for input that is
|
|
50
|
+
# truly truncated.
|
|
51
|
+
def self.feed(inflater, data, &)
|
|
52
|
+
inflater.inflate(data, &)
|
|
53
|
+
rescue Zlib::BufError
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.finish_stream(stream, out)
|
|
58
|
+
out << next_chunk(stream) until stream.finished?
|
|
59
|
+
out
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Each finish makes progress, so one that returns nothing means the
|
|
63
|
+
# stream can't end: the compressed input is truncated
|
|
64
|
+
def self.next_chunk(stream)
|
|
65
|
+
chunk = stream.finish
|
|
66
|
+
raise Zlib::BufError, 'buffer error' if chunk.empty?
|
|
67
|
+
|
|
68
|
+
chunk
|
|
69
|
+
end
|
|
70
|
+
|
|
32
71
|
# False when even the largest possible expansion stays within max_bytes,
|
|
33
72
|
# so the value can be inflated in one step
|
|
34
73
|
def self.may_exceed?(data, max_bytes)
|
|
@@ -43,16 +82,15 @@ module Dalli
|
|
|
43
82
|
# with Zlib::Inflate.inflate; finish would return it as output
|
|
44
83
|
break if inflater.finished?
|
|
45
84
|
end
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
append_within_limit(out, inflater.finish, max_bytes)
|
|
85
|
+
append_within_limit(out, next_chunk(inflater), max_bytes) until inflater.finished?
|
|
86
|
+
out
|
|
49
87
|
ensure
|
|
50
88
|
inflater.close
|
|
51
89
|
end
|
|
52
90
|
|
|
53
91
|
# Both yielded and returned output count toward the limit
|
|
54
92
|
def self.inflate_slice(inflater, slice, out, max_bytes)
|
|
55
|
-
rest = inflater
|
|
93
|
+
rest = feed(inflater, slice) { |chunk| append_within_limit(out, chunk, max_bytes) }
|
|
56
94
|
append_within_limit(out, rest, max_bytes)
|
|
57
95
|
end
|
|
58
96
|
|
|
@@ -70,19 +108,18 @@ module Dalli
|
|
|
70
108
|
# entry.
|
|
71
109
|
##
|
|
72
110
|
class GzipCompressor
|
|
111
|
+
# MAX_WBITS + 16 makes zlib write and read the gzip format (and check its CRC)
|
|
112
|
+
WINDOW_BITS = Zlib::MAX_WBITS + 16
|
|
113
|
+
|
|
73
114
|
def self.compress(data)
|
|
74
|
-
|
|
75
|
-
gz = Zlib::GzipWriter.new(io)
|
|
76
|
-
gz.write(data)
|
|
77
|
-
gz.close
|
|
78
|
-
io.string
|
|
115
|
+
Compressor.deflate_fully(Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION, WINDOW_BITS), data)
|
|
79
116
|
end
|
|
80
117
|
|
|
81
118
|
def self.decompress(data, max_bytes: nil)
|
|
82
|
-
|
|
119
|
+
inflater = Zlib::Inflate.new(WINDOW_BITS)
|
|
120
|
+
return Compressor.inflate_fully(inflater, data) unless Compressor.may_exceed?(data, max_bytes)
|
|
83
121
|
|
|
84
|
-
|
|
85
|
-
Compressor.inflate_within_limit(Zlib::Inflate.new(Zlib::MAX_WBITS + 16), data, max_bytes)
|
|
122
|
+
Compressor.inflate_within_limit(inflater, data, max_bytes)
|
|
86
123
|
end
|
|
87
124
|
end
|
|
88
125
|
end
|
data/lib/dalli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dalli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.3.
|
|
4
|
+
version: 5.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter M. Goldstein
|
|
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
90
90
|
- !ruby/object:Gem::Version
|
|
91
91
|
version: '0'
|
|
92
92
|
requirements: []
|
|
93
|
-
rubygems_version: 4.0.
|
|
93
|
+
rubygems_version: 4.0.24
|
|
94
94
|
specification_version: 4
|
|
95
95
|
summary: High performance memcached client for Ruby
|
|
96
96
|
test_files: []
|