dalli 3.2.1 → 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f81141d870bf96f502734833c9e63678c4f034a2e5cdb6a28bf1fe54b5a6f8f2
4
- data.tar.gz: abbb39311cd429b8546397b1c5ba0555024f104e49a6b23fd97b3386408cb5e6
3
+ metadata.gz: f0ef39f4ff4e9e465b2522707f3c4eea85a94373ba0d3de4b9d940830001b118
4
+ data.tar.gz: 35cb362ec6075818f062106769481e92c90752936ecaf9a00fae25725ee4ea94
5
5
  SHA512:
6
- metadata.gz: 1a6af753aa61a1e80ed734eabb2fa70b8c14e2c1d2fd43a8f95f600732c02d2de08018cb9f41ce776d7796815f8da52fff4a95b05fccb732fe58506d6c38cb2f
7
- data.tar.gz: 1724f003506854bc011c90402584a898534059b022de87385e0f8f2b24879897f23d33219f732489212aaf86b58eaa3c6d6ceb4e86c028daacd5180bc3be07ae
6
+ metadata.gz: 0c6b2b205551fb10fb2e49ab7c3c3eba3c552c0bc4b8132783b51f6cdc7a9ddd4c272bd24ed13f9d78e29353e3b84daec001b2691ad630bdfd517bb7af86fd54
7
+ data.tar.gz: 6ef9f6733d8e6d5f8a6bf8fb7d782e99c450494e03d4e5fe46037b77665682df63eaa9a3eb05007d1720b175564c8e91524c0df92d0856dc1f68066501732a06
@@ -4,6 +4,20 @@ Dalli Changelog
4
4
  Unreleased
5
5
  ==========
6
6
 
7
+ 3.2.3
8
+ ==========
9
+
10
+ - Sanitize CAS inputs to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
11
+ - Sanitize input to flush command to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
12
+ - Namespaces passed as procs are now evaluated every time, as opposed to just on initialization (nrw505)
13
+ - Fix missing require of uri in ServerConfigParser (adam12)
14
+ - Fix link to the CHANGELOG.md file in README.md (rud)
15
+
16
+ 3.2.2
17
+ ==========
18
+
19
+ - Ensure apps are resilient against old session ids (kbrock)
20
+
7
21
  3.2.1
8
22
  ==========
9
23
 
@@ -118,6 +132,9 @@ Unreleased
118
132
  * The Rack session adapter has been refactored to remove support for thread-unsafe
119
133
  configurations. You will need to include the `connection_pool` gem in
120
134
  your Gemfile to ensure session operations are thread-safe.
135
+ * When using namespaces, the algorithm for calculating truncated keys was
136
+ changed. Non-truncated keys and truncated keys for the non-namespace
137
+ case were left unchanged.
121
138
 
122
139
  - Raise NetworkError when multi response gets into corrupt state (mervync, #783)
123
140
  - Validate servers argument (semaperepelitsa, petergoldstein, #776)
data/Gemfile CHANGED
@@ -5,12 +5,5 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  group :test do
8
- gem 'minitest'
9
- gem 'rake'
10
- gem 'rubocop'
11
- gem 'rubocop-minitest'
12
- gem 'rubocop-performance'
13
- gem 'rubocop-rake'
14
8
  gem 'ruby-prof', platform: :mri
15
- gem 'simplecov'
16
9
  end
data/README.md CHANGED
@@ -23,11 +23,11 @@ The name is a variant of Salvador Dali for his famous painting [The Persistence
23
23
  * [Announcements](https://github.com/petergoldstein/dalli/discussions/categories/announcements) - Announcements of interest to the Dalli community will be posted here.
24
24
  * [Bug Reports](https://github.com/petergoldstein/dalli/issues) - If you discover a problem with Dalli, please submit a bug report in the tracker.
25
25
  * [Forum](https://github.com/petergoldstein/dalli/discussions/categories/q-a) - If you have questions about Dalli, please post them here.
26
- * [Client API](https://www.rubydoc.info/github/petergoldstein/dalli/master/Dalli/Client) - Ruby documentation for the `Dalli::Client` API
26
+ * [Client API](https://rubydoc.info/github/petergoldstein/dalli/Dalli/Client) - Ruby documentation for the `Dalli::Client` API
27
27
 
28
28
  ## Contributing
29
29
 
30
- If you have a fix you wish to provide, please fork the code, fix in your local project and then send a pull request on github. Please ensure that you include a test which verifies your fix and update `History.md` with a one sentence description of your fix so you get credit as a contributor.
30
+ If you have a fix you wish to provide, please fork the code, fix in your local project and then send a pull request on github. Please ensure that you include a test which verifies your fix and update the [changelog](CHANGELOG.md) with a one sentence description of your fix so you get credit as a contributor.
31
31
 
32
32
  ## Appreciation
33
33
 
@@ -61,7 +61,7 @@ module Dalli
61
61
  def key_with_namespace(key)
62
62
  return key if namespace.nil?
63
63
 
64
- "#{namespace}#{NAMESPACE_SEPARATOR}#{key}"
64
+ "#{evaluate_namespace}#{NAMESPACE_SEPARATOR}#{key}"
65
65
  end
66
66
 
67
67
  def key_without_namespace(key)
@@ -75,6 +75,8 @@ module Dalli
75
75
  end
76
76
 
77
77
  def namespace_regexp
78
+ return /\A#{Regexp.escape(evaluate_namespace)}:/ if namespace.is_a?(Proc)
79
+
78
80
  @namespace_regexp ||= /\A#{Regexp.escape(namespace)}:/.freeze unless namespace.nil?
79
81
  end
80
82
 
@@ -87,9 +89,15 @@ module Dalli
87
89
  def namespace_from_options
88
90
  raw_namespace = @key_options[:namespace]
89
91
  return nil unless raw_namespace
90
- return raw_namespace.call.to_s if raw_namespace.is_a?(Proc)
92
+ return raw_namespace.to_s unless raw_namespace.is_a?(Proc)
93
+
94
+ raw_namespace
95
+ end
96
+
97
+ def evaluate_namespace
98
+ return namespace.call.to_s if namespace.is_a?(Proc)
91
99
 
92
- raw_namespace.to_s
100
+ namespace
93
101
  end
94
102
 
95
103
  ##
@@ -167,7 +167,7 @@ module Dalli
167
167
  groups = @ring.keys_grouped_by_server(keys)
168
168
  if (unfound_keys = groups.delete(nil))
169
169
  Dalli.logger.debug do
170
- "unable to get keys for #{unfound_keys.length} keys "\
170
+ "unable to get keys for #{unfound_keys.length} keys " \
171
171
  'because no matching server was found'
172
172
  end
173
173
  end
@@ -127,11 +127,11 @@ module Dalli
127
127
  end
128
128
 
129
129
  def username
130
- @options[:username] || ENV['MEMCACHE_USERNAME']
130
+ @options[:username] || ENV.fetch('MEMCACHE_USERNAME', nil)
131
131
  end
132
132
 
133
133
  def password
134
- @options[:password] || ENV['MEMCACHE_PASSWORD']
134
+ @options[:password] || ENV.fetch('MEMCACHE_PASSWORD', nil)
135
135
  end
136
136
 
137
137
  def require_auth?
@@ -31,7 +31,7 @@ module Dalli
31
31
  cmd << ' c' unless %i[append prepend].include?(mode)
32
32
  cmd << ' b' if base64
33
33
  cmd << " F#{bitflags}" if bitflags
34
- cmd << " C#{cas}" if cas && !cas.zero?
34
+ cmd << cas_string(cas)
35
35
  cmd << " T#{ttl}" if ttl
36
36
  cmd << " M#{mode_to_token(mode)}"
37
37
  cmd << ' q' if quiet
@@ -43,7 +43,7 @@ module Dalli
43
43
  def self.meta_delete(key:, cas: nil, ttl: nil, base64: false, quiet: false)
44
44
  cmd = "md #{key}"
45
45
  cmd << ' b' if base64
46
- cmd << " C#{cas}" if cas && !cas.zero?
46
+ cmd << cas_string(cas)
47
47
  cmd << " T#{ttl}" if ttl
48
48
  cmd << ' q' if quiet
49
49
  cmd + TERMINATOR
@@ -54,8 +54,9 @@ module Dalli
54
54
  cmd << ' b' if base64
55
55
  cmd << " D#{delta}" if delta
56
56
  cmd << " J#{initial}" if initial
57
- cmd << " C#{cas}" if cas && !cas.zero?
58
- cmd << " N#{ttl}" if ttl
57
+ # Always set a TTL if an initial value is specified
58
+ cmd << " N#{ttl || 0}" if ttl || initial
59
+ cmd << cas_string(cas)
59
60
  cmd << ' q' if quiet
60
61
  cmd << " M#{incr ? 'I' : 'D'}"
61
62
  cmd + TERMINATOR
@@ -75,7 +76,7 @@ module Dalli
75
76
 
76
77
  def self.flush(delay: nil, quiet: false)
77
78
  cmd = +'flush_all'
78
- cmd << " #{delay}" if delay
79
+ cmd << " #{parse_to_64_bit_int(delay, 0)}" if delay
79
80
  cmd << ' noreply' if quiet
80
81
  cmd + TERMINATOR
81
82
  end
@@ -102,6 +103,18 @@ module Dalli
102
103
  end
103
104
  end
104
105
  # rubocop:enable Metrics/MethodLength
106
+
107
+ def self.cas_string(cas)
108
+ cas = parse_to_64_bit_int(cas, nil)
109
+ cas.nil? || cas.zero? ? '' : " C#{cas}"
110
+ end
111
+
112
+ def self.parse_to_64_bit_int(val, default)
113
+ val.nil? ? nil : Integer(val)
114
+ rescue ArgumentError
115
+ # Sanitize to default if it isn't parsable as an integer
116
+ default
117
+ end
105
118
  end
106
119
  end
107
120
  end
@@ -44,6 +44,7 @@ module Dalli
44
44
  end
45
45
 
46
46
  def touch(key, ttl)
47
+ ttl = TtlSanitizer.sanitize(ttl)
47
48
  encoded_key, base64 = KeyRegularizer.encode(key)
48
49
  req = RequestFormatter.meta_get(key: encoded_key, ttl: ttl, value: false, base64: base64)
49
50
  write(req)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+
3
5
  module Dalli
4
6
  module Protocol
5
7
  ##
@@ -40,7 +40,7 @@ module Dalli
40
40
  def self.apply_defaults(arg)
41
41
  return arg unless arg.nil?
42
42
 
43
- ENV[ENV_VAR_NAME] || DEFAULT_SERVERS
43
+ ENV.fetch(ENV_VAR_NAME, nil) || DEFAULT_SERVERS
44
44
  end
45
45
 
46
46
  def self.validate_type(arg)
data/lib/dalli/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dalli
4
- VERSION = '3.2.1'
4
+ VERSION = '3.2.3'
5
5
 
6
6
  MIN_SUPPORTED_MEMCACHED_VERSION = '1.4'
7
7
  end
@@ -82,6 +82,9 @@ module Rack
82
82
  def write_session(_req, sid, session, options)
83
83
  return false unless sid
84
84
 
85
+ key = memcached_key_from_sid(sid)
86
+ return false unless key
87
+
85
88
  with_dalli_client(false) do |dc|
86
89
  dc.set(memcached_key_from_sid(sid), session, ttl(options[:expire_after]))
87
90
  sid
@@ -90,7 +93,8 @@ module Rack
90
93
 
91
94
  def delete_session(_req, sid, options)
92
95
  with_dalli_client do |dc|
93
- dc.delete(memcached_key_from_sid(sid))
96
+ key = memcached_key_from_sid(sid)
97
+ dc.delete(key) if key
94
98
  generate_sid_with(dc) unless options[:drop]
95
99
  end
96
100
  end
@@ -98,20 +102,24 @@ module Rack
98
102
  private
99
103
 
100
104
  def memcached_key_from_sid(sid)
101
- sid.private_id
105
+ sid.private_id if sid.respond_to?(:private_id)
102
106
  end
103
107
 
104
108
  def existing_session_for_sid(client, sid)
105
109
  return nil unless sid && !sid.empty?
106
110
 
107
- client.get(memcached_key_from_sid(sid))
111
+ key = memcached_key_from_sid(sid)
112
+ return nil if key.nil?
113
+
114
+ client.get(key)
108
115
  end
109
116
 
110
117
  def create_sid_with_empty_session(client)
111
118
  loop do
112
119
  sid = generate_sid_with(client)
120
+ key = memcached_key_from_sid(sid)
113
121
 
114
- break sid if client.add(memcached_key_from_sid(sid), {}, @default_ttl)
122
+ break sid if key && client.add(key, {}, @default_ttl)
115
123
  end
116
124
  end
117
125
 
@@ -119,7 +127,8 @@ module Rack
119
127
  loop do
120
128
  raw_sid = generate_sid
121
129
  sid = raw_sid.is_a?(String) ? Rack::Session::SessionId.new(raw_sid) : raw_sid
122
- break sid unless client.get(memcached_key_from_sid(sid))
130
+ key = memcached_key_from_sid(sid)
131
+ break sid unless key && client.get(key)
123
132
  end
124
133
  end
125
134
 
@@ -161,7 +170,7 @@ module Rack
161
170
  def ensure_connection_pool_added!
162
171
  require 'connection_pool'
163
172
  rescue LoadError => e
164
- warn "You don't have connection_pool installed in your application. "\
173
+ warn "You don't have connection_pool installed in your application. " \
165
174
  'Please add it to your Gemfile and run bundle install'
166
175
  raise e
167
176
  end
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: 3.2.1
4
+ version: 3.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter M. Goldstein
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-02-14 00:00:00.000000000 Z
12
+ date: 2022-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: connection_pool
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '5'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '5'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: rack
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -45,6 +59,20 @@ dependencies:
45
59
  - - ">="
46
60
  - !ruby/object:Gem::Version
47
61
  version: 2.2.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '13.0'
48
76
  - !ruby/object:Gem::Dependency
49
77
  name: rubocop
50
78
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +129,20 @@ dependencies:
101
129
  - - ">="
102
130
  - !ruby/object:Gem::Version
103
131
  version: '0'
132
+ - !ruby/object:Gem::Dependency
133
+ name: simplecov
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
104
146
  description: High performance memcached client for Ruby
105
147
  email:
106
148
  - peter.m.goldstein@gmail.com
@@ -109,8 +151,8 @@ executables: []
109
151
  extensions: []
110
152
  extra_rdoc_files: []
111
153
  files:
154
+ - CHANGELOG.md
112
155
  - Gemfile
113
- - History.md
114
156
  - LICENSE
115
157
  - README.md
116
158
  - lib/dalli.rb
@@ -164,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
206
  - !ruby/object:Gem::Version
165
207
  version: '0'
166
208
  requirements: []
167
- rubygems_version: 3.3.7
209
+ rubygems_version: 3.3.24
168
210
  signing_key:
169
211
  specification_version: 4
170
212
  summary: High performance memcached client for Ruby