rack-utf8_sanitizer 1.9.0 → 1.10.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9893353fe731d6c942263ff57af911b10d1c9f88ba2c2c2b56bb7a76586935e5
4
- data.tar.gz: eeeaca39f55d680abe2707fa1aaadfe34eed06de2dd848506d184ae4ff326a8d
3
+ metadata.gz: c33079dde3e7e3efb8c46742a50303be620b316243b5e11c5f026a89ce29bf7d
4
+ data.tar.gz: 537ff74a7f0c3edfe1bc3904540ae3c95c4ed08f15198a8872bf25a055376673
5
5
  SHA512:
6
- metadata.gz: 28cfbadcc1fbbf0678db3b51259618a9c9897c0cb78bcd8b8f5d87c91eddb44873a7a77fb21b9db47bcc704cb7df17d942c50436475858d0d9fcc17c2a8b59ce
7
- data.tar.gz: 7e781931df60e405d533f5eb832416510a431a1c6fa74baeabffb9499533d9eba2f97ffa24f89ed79a193de5f6715c0461fff4fb0403c863a3643e4aaabbcf0a
6
+ metadata.gz: 787fbd5b17de52dbd26bcef3e64acb359d026eb6eeb3f5900fa0fe641980235f795c0fa2067693ab2630b2781e8d8a9c03fda141e7ad2fbca6c65f663b571795
7
+ data.tar.gz: be57486cc8be56299013bf3b101363702a8bc2af26746293e6661dd762b11737a5ae76c1f14373d5200772a3e229b19c7687f3c1855fc1950256cf4e750e3ca8
@@ -10,10 +10,10 @@ jobs:
10
10
  strategy:
11
11
  fail-fast: false
12
12
  matrix:
13
- ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", "3.2", ruby-head, jruby-9.2, jruby-9.3, jruby-head]
13
+ ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "3.3", ruby-head, jruby-9.2, jruby-9.3, jruby-head]
14
14
 
15
15
  steps:
16
- - uses: actions/checkout@v3
16
+ - uses: actions/checkout@v4
17
17
  - name: Set up Ruby
18
18
  uses: ruby/setup-ruby@v1
19
19
  with:
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in rack-utf8_sanitizer.gemspec
data/README.md CHANGED
@@ -113,7 +113,7 @@ config.middleware.insert 0, Rack::UTF8Sanitizer, strategy: :exception
113
113
  ```
114
114
 
115
115
  ```ruby
116
- replace_string = lambda do |_invalid|
116
+ replace_string = lambda do |_invalid, sanitize_null_bytes: false|
117
117
  Rails.logger.warn('Replacing invalid string')
118
118
 
119
119
  '<Bad Encoding>'.freeze
@@ -122,6 +122,10 @@ end
122
122
  config.middleware.insert 0, Rack::UTF8Sanitizer, strategy: replace_string
123
123
  ```
124
124
 
125
+ ### Sanitizing Null Bytes
126
+
127
+ While null bytes are valid UTF-8, it can be useful to further restrict the valid character set to exclude null bytes. For example, PostgreSQL text columns do not allow storing null bytes. Passing `sanitize_null_bytes: true` in the configuration hash enables sanitizing null bytes, and the two built-in strategies both support this feature. Custom strategies should accept a keyword argument `sanitize_null_bytes` containing this configuration value.
128
+
125
129
  ## Contributing
126
130
 
127
131
  1. Fork it
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
 
3
5
  task :default => :spec
@@ -1,12 +1,13 @@
1
1
  # encoding: ascii-8bit
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'uri'
4
5
  require 'stringio'
6
+ require 'rack/request'
5
7
 
6
8
  module Rack
7
9
  class UTF8Sanitizer
8
10
  StringIO = ::StringIO
9
- BAD_REQUEST = [400, { "Content-Type" => "text/plain" }, ["Bad Request"]]
10
11
  NULL_BYTE_REGEX = /\x00/.freeze
11
12
 
12
13
  class NullByteInString < StandardError; end
@@ -27,29 +28,31 @@ module Rack
27
28
  begin
28
29
  env = sanitize(env)
29
30
  rescue EOFError
30
- return BAD_REQUEST
31
+ return [400, { "Content-Type" => "text/plain" }, ["Bad Request"]]
31
32
  end
32
33
  @app.call(env)
33
34
  end
34
35
 
35
36
  DEFAULT_STRATEGIES = {
36
37
  replace: lambda do |input, sanitize_null_bytes: false|
37
- if sanitize_null_bytes
38
- input = input.gsub(NULL_BYTE_REGEX, "")
39
- end
40
38
  input.
41
39
  force_encoding(Encoding::ASCII_8BIT).
42
40
  encode!(Encoding::UTF_8,
43
41
  invalid: :replace,
44
42
  undef: :replace)
43
+ if sanitize_null_bytes
44
+ input = input.gsub(NULL_BYTE_REGEX, "")
45
+ end
46
+ input
45
47
  end,
46
48
  exception: lambda do |input, sanitize_null_bytes: false|
47
- if sanitize_null_bytes && input =~ NULL_BYTE_REGEX
48
- raise NullByteInString
49
- end
50
49
  input.
51
50
  force_encoding(Encoding::ASCII_8BIT).
52
51
  encode!(Encoding::UTF_8)
52
+ if sanitize_null_bytes && NULL_BYTE_REGEX.match?(input)
53
+ raise NullByteInString
54
+ end
55
+ input
53
56
  end
54
57
  }.freeze
55
58
 
@@ -62,20 +65,20 @@ module Rack
62
65
  ORIGINAL_FULLPATH
63
66
  ORIGINAL_SCRIPT_NAME
64
67
  SERVER_NAME
65
- ).map(&:freeze).freeze
68
+ ).freeze
66
69
 
67
70
  SANITIZABLE_CONTENT_TYPES = %w(
68
71
  text/plain
69
72
  application/x-www-form-urlencoded
70
73
  application/json
71
74
  text/javascript
72
- ).map(&:freeze).freeze
75
+ ).freeze
73
76
 
74
77
  URI_ENCODED_CONTENT_TYPES = %w(
75
78
  application/x-www-form-urlencoded
76
- ).map(&:freeze).freeze
79
+ ).freeze
77
80
 
78
- HTTP_ = 'HTTP_'.freeze
81
+ HTTP_ = 'HTTP_'
79
82
 
80
83
  def sanitize(env)
81
84
  sanitize_rack_input(env)
@@ -113,17 +116,17 @@ module Rack
113
116
  end
114
117
 
115
118
  def sanitize_rack_input(env)
116
- # https://github.com/rack/rack/blob/master/lib/rack/request.rb#L42
117
- # Logic borrowed from Rack::Request#media_type,#media_type_params,#content_charset
118
- # Ignoring charset in content type.
119
- content_type = env['CONTENT_TYPE']
120
- content_type &&= content_type.split(/\s*[;,]\s*/, 2).first
121
- content_type &&= content_type.downcase
119
+ request = Rack::Request.new(env)
120
+ content_type = request.media_type
122
121
  return unless @sanitizable_content_types.any? {|type| content_type == type }
122
+
123
+ charset = request.content_charset
124
+ return if charset && charset.downcase != 'utf-8'
125
+
123
126
  uri_encoded = URI_ENCODED_CONTENT_TYPES.any? {|type| content_type == type}
124
127
 
125
128
  if env['rack.input']
126
- sanitized_input = sanitize_io(env['rack.input'], uri_encoded)
129
+ sanitized_input = sanitize_io(env['rack.input'], uri_encoded, env['CONTENT_LENGTH']&.to_i)
127
130
 
128
131
  env['rack.input'] = sanitized_input
129
132
  env['CONTENT_LENGTH'] &&= sanitized_input.size.to_s
@@ -165,8 +168,12 @@ module Rack
165
168
  end
166
169
  end
167
170
 
168
- def sanitize_io(io, uri_encoded = false)
169
- input = io.read
171
+ def sanitize_io(io, uri_encoded = false, content_length = nil)
172
+ input = if content_length && content_length >= 0
173
+ io.read(content_length)
174
+ else
175
+ io.read
176
+ end
170
177
  sanitized_input = sanitize_string(strip_byte_order_mark(input))
171
178
  if uri_encoded
172
179
  sanitized_input = sanitize_uri_encoded_string(sanitized_input).
@@ -249,7 +256,7 @@ module Rack
249
256
  # Performs the reverse function of `unescape_unreserved`. Unlike
250
257
  # the previous function, we can reuse the logic in URI#encode
251
258
  def escape_unreserved(input)
252
- URI::DEFAULT_PARSER.escape(input, UNSAFE)
259
+ URI::RFC2396_PARSER.escape(input, UNSAFE)
253
260
  end
254
261
 
255
262
  def sanitize_string(input)
@@ -274,7 +281,7 @@ module Rack
274
281
  end
275
282
  end
276
283
 
277
- UTF8_BOM = "\xef\xbb\xbf".force_encoding(Encoding::BINARY).freeze
284
+ UTF8_BOM = "\xef\xbb\xbf".dup.force_encoding(Encoding::BINARY).freeze
278
285
  UTF8_BOM_SIZE = UTF8_BOM.bytesize
279
286
 
280
287
  def strip_byte_order_mark(input)
@@ -1,21 +1,22 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  Gem::Specification.new do |gem|
4
5
  gem.name = "rack-utf8_sanitizer"
5
- gem.version = '1.9.0'
6
- gem.authors = ["whitequark"]
6
+ gem.version = '1.10.0'
7
+ gem.authors = ["Catherine"]
7
8
  gem.license = "MIT"
8
9
  gem.email = ["whitequark@whitequark.org"]
9
- gem.description = %{Rack::UTF8Sanitizer is a Rack middleware which cleans up } <<
10
- %{invalid UTF8 characters in request URI and headers.}
10
+ gem.description = "Rack::UTF8Sanitizer is a Rack middleware which cleans up " \
11
+ "invalid UTF8 characters in request URI and headers."
11
12
  gem.summary = gem.description
12
- gem.homepage = "http://github.com/whitequark/rack-utf8_sanitizer"
13
+ gem.homepage = "https://github.com/whitequark/rack-utf8_sanitizer"
13
14
 
14
15
  gem.files = `git ls-files`.split($/)
15
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
17
  gem.require_paths = ["lib"]
17
18
 
18
- gem.required_ruby_version = '>= 1.9.3'
19
+ gem.required_ruby_version = '>= 2.3'
19
20
 
20
21
  gem.add_dependency "rack", '>= 1.0', '< 4.0'
21
22
 
@@ -1,4 +1,5 @@
1
1
  # encoding:ascii-8bit
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bacon/colored_output'
4
5
  require 'cgi'
@@ -31,7 +32,7 @@ describe Rack::UTF8Sanitizer do
31
32
 
32
33
  describe "with invalid host input" do
33
34
  it "sanitizes host entity (SERVER_NAME)" do
34
- host = "host\xD0".force_encoding('UTF-8')
35
+ host = "host\xD0".dup.force_encoding('UTF-8')
35
36
  env = @app.({ "SERVER_NAME" => host })
36
37
  result = env["SERVER_NAME"]
37
38
 
@@ -42,8 +43,8 @@ describe Rack::UTF8Sanitizer do
42
43
 
43
44
  describe "with invalid UTF-8 input" do
44
45
  before do
45
- @plain_input = "foo\xe0".force_encoding('UTF-8')
46
- @uri_input = "http://bar/foo%E0".force_encoding('UTF-8')
46
+ @plain_input = "foo\xe0".dup.force_encoding('UTF-8')
47
+ @uri_input = "http://bar/foo%E0".dup.force_encoding('UTF-8')
47
48
  end
48
49
 
49
50
  behaves_like :does_sanitize_plain
@@ -52,7 +53,7 @@ describe Rack::UTF8Sanitizer do
52
53
 
53
54
  describe "with invalid, incorrectly percent-encoded UTF-8 URI input" do
54
55
  before do
55
- @uri_input = "http://bar/foo%E0\xe0".force_encoding('UTF-8')
56
+ @uri_input = "http://bar/foo%E0\xe0".dup.force_encoding('UTF-8')
56
57
  end
57
58
 
58
59
  behaves_like :does_sanitize_uri
@@ -100,8 +101,8 @@ describe Rack::UTF8Sanitizer do
100
101
 
101
102
  describe "with valid UTF-8 input" do
102
103
  before do
103
- @plain_input = "foo bar лол".force_encoding('UTF-8')
104
- @uri_input = "http://bar/foo+bar+%D0%BB%D0%BE%D0%BB".force_encoding('UTF-8')
104
+ @plain_input = "foo bar лол".dup.force_encoding('UTF-8')
105
+ @uri_input = "http://bar/foo+bar+%D0%BB%D0%BE%D0%BB".dup.force_encoding('UTF-8')
105
106
  end
106
107
 
107
108
  behaves_like :identity_plain
@@ -109,7 +110,7 @@ describe Rack::UTF8Sanitizer do
109
110
 
110
111
  describe "with URI characters from reserved range" do
111
112
  before do
112
- @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".force_encoding('UTF-8')
113
+ @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".dup.force_encoding('UTF-8')
113
114
  end
114
115
 
115
116
  behaves_like :identity_uri
@@ -118,7 +119,7 @@ describe Rack::UTF8Sanitizer do
118
119
 
119
120
  describe "with valid, not percent-encoded UTF-8 URI input" do
120
121
  before do
121
- @uri_input = "http://bar/foo+bar+лол".force_encoding('UTF-8')
122
+ @uri_input = "http://bar/foo+bar+лол".dup.force_encoding('UTF-8')
122
123
  @encoded = "http://bar/foo+bar+#{CGI.escape("лол")}"
123
124
  end
124
125
 
@@ -152,8 +153,8 @@ describe Rack::UTF8Sanitizer do
152
153
 
153
154
  describe "with frozen strings" do
154
155
  before do
155
- @plain_input = "bar baz".freeze
156
- @uri_input = "http://bar/bar+baz".freeze
156
+ @plain_input = "bar baz"
157
+ @uri_input = "http://bar/bar+baz"
157
158
  end
158
159
 
159
160
  it "preserves the frozen? status of input" do
@@ -165,9 +166,24 @@ describe Rack::UTF8Sanitizer do
165
166
  end
166
167
  end
167
168
 
169
+ describe "with mutable strings" do
170
+ before do
171
+ @plain_input = "bar baz".dup
172
+ @uri_input = "http://bar/bar+baz".dup
173
+ end
174
+
175
+ it "preserves the frozen? status of input" do
176
+ env = @app.({ "HTTP_USER_AGENT" => @plain_input,
177
+ "REQUEST_PATH" => @uri_input })
178
+
179
+ env["HTTP_USER_AGENT"].should.not.be.frozen
180
+ env["REQUEST_PATH"].should.not.be.frozen
181
+ end
182
+ end
183
+
168
184
  describe "with symbols in the env" do
169
185
  before do
170
- @uri_input = "http://bar/foo%E0\xe0".force_encoding('UTF-8')
186
+ @uri_input = "http://bar/foo%E0\xe0".dup.force_encoding('UTF-8')
171
187
  end
172
188
 
173
189
  it "sanitizes REQUEST_PATH with invalid UTF-8 URI input" do
@@ -183,7 +199,7 @@ describe Rack::UTF8Sanitizer do
183
199
 
184
200
  describe "with form data" do
185
201
  def request_env
186
- @plain_input = "foo bar лол".force_encoding('UTF-8')
202
+ @plain_input = "foo bar лол".dup.force_encoding('UTF-8')
187
203
  {
188
204
  "REQUEST_METHOD" => "POST",
189
205
  "CONTENT_TYPE" => "application/x-www-form-urlencoded;foo=bar",
@@ -193,7 +209,7 @@ describe Rack::UTF8Sanitizer do
193
209
  end
194
210
 
195
211
  def sanitize_form_data(request_env = request_env())
196
- @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".force_encoding('UTF-8')
212
+ @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".dup.force_encoding('UTF-8')
197
213
  @response_env = @app.(request_env)
198
214
  sanitized_input = @response_env['rack.input'].read
199
215
 
@@ -219,6 +235,16 @@ describe Rack::UTF8Sanitizer do
219
235
  @response_env.should == [400, {"Content-Type"=>"text/plain"}, ["Bad Request"]]
220
236
  end
221
237
 
238
+ it "Bad Request response can safety be mutated" do
239
+ @rack_input = BrokenIO.new
240
+ response_env = @app.(request_env)
241
+ response_env.should == [400, {"Content-Type"=>"text/plain"}, ["Bad Request"]]
242
+ response_env[1]["Set-Cookie"] = "you_are_admin"
243
+
244
+ response_env = @app.(request_env)
245
+ response_env[1]["Set-Cookie"].should == nil
246
+ end
247
+
222
248
  it "sanitizes StringIO rack.input" do
223
249
  input = "foo=bla&quux=bar"
224
250
  @rack_input = StringIO.new input
@@ -252,6 +278,18 @@ describe Rack::UTF8Sanitizer do
252
278
  end
253
279
  end
254
280
 
281
+ it "sanitizes the rack body if the charset is present and utf-8" do
282
+ input = "name=#{CGI.escape("まつもと")}"
283
+ @rack_input = StringIO.new input
284
+
285
+ env = request_env.update('CONTENT_TYPE' => "application/x-www-form-urlencoded; charset=utf-8")
286
+ sanitize_form_data(env) do |sanitized_input|
287
+ sanitized_input.encoding.should == Encoding::UTF_8
288
+ sanitized_input.should.be.valid_encoding
289
+ sanitized_input.should == input
290
+ end
291
+ end
292
+
255
293
  it "strip UTF-8 BOM from StringIO rack.input" do
256
294
  input = %(\xef\xbb\xbf{"Hello": "World"})
257
295
  @rack_input = StringIO.new input
@@ -327,6 +365,18 @@ describe Rack::UTF8Sanitizer do
327
365
  end
328
366
  end
329
367
 
368
+ it "does not sanitize the rack body if the charset is present and not utf-8" do
369
+ input = "name=".encode("Shift_JIS") + CGI.escape("まつもと".encode("Shift_JIS", "UTF-8"))
370
+ @rack_input = StringIO.new input
371
+
372
+ env = request_env.update('CONTENT_TYPE' => "application/x-www-form-urlencoded; charset=Shift_JIS")
373
+ sanitize_form_data(env) do |sanitized_input|
374
+ sanitized_input.encoding.should == Encoding::SHIFT_JIS
375
+ sanitized_input.should.be.valid_encoding
376
+ sanitized_input.should == input
377
+ end
378
+ end
379
+
330
380
  it "adjusts content-length when replacing input" do
331
381
  input = "foo=bla&quux=bar\xED"
332
382
  @rack_input = StringIO.new input
@@ -351,25 +401,25 @@ describe Rack::UTF8Sanitizer do
351
401
 
352
402
  it "optionally sanitizes null bytes with the replace strategy" do
353
403
  @app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
354
- input = "foo=bla&quux=bar\x00"
404
+ input = "foo=bla\xED&quux=bar\x00"
355
405
  @rack_input = StringIO.new input
356
406
 
357
407
  sanitize_form_data do |sanitized_input|
358
408
  sanitized_input.encoding.should == Encoding::UTF_8
359
409
  sanitized_input.should.be.valid_encoding
360
- sanitized_input.should == "foo=bla&quux=bar"
410
+ sanitized_input.should == "foo=bla%EF%BF%BD&quux=bar"
361
411
  end
362
412
  end
363
413
 
364
414
  it "optionally sanitizes encoded null bytes with the replace strategy" do
365
415
  @app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true)
366
- input = "foo=bla&quux=bar%00"
416
+ input = "foo=bla%ED&quux=bar%00"
367
417
  @rack_input = StringIO.new input
368
418
 
369
419
  sanitize_form_data do |sanitized_input|
370
420
  sanitized_input.encoding.should == Encoding::UTF_8
371
421
  sanitized_input.should.be.valid_encoding
372
- sanitized_input.should == "foo=bla&quux=bar"
422
+ sanitized_input.should == "foo=bla%EF%BF%BD&quux=bar"
373
423
  end
374
424
  end
375
425
 
@@ -392,6 +442,16 @@ describe Rack::UTF8Sanitizer do
392
442
  sanitize_form_data
393
443
  end
394
444
  end
445
+
446
+ it "gives precedence to encoding errors with the exception strategy and null byte sanitisation" do
447
+ @app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true, strategy: :exception)
448
+ input = "foo=bla\x00&quux=bar\xED"
449
+ @rack_input = StringIO.new input
450
+
451
+ should.raise(EncodingError) do
452
+ sanitize_form_data
453
+ end
454
+ end
395
455
  end
396
456
 
397
457
  describe "with custom content-type" do
@@ -424,7 +484,7 @@ describe Rack::UTF8Sanitizer do
424
484
 
425
485
  describe "with custom content-type" do
426
486
  def request_env
427
- @plain_input = "foo bar лол".force_encoding('UTF-8')
487
+ @plain_input = "foo bar лол".dup.force_encoding('UTF-8')
428
488
  {
429
489
  "REQUEST_METHOD" => "POST",
430
490
  "CONTENT_TYPE" => "application/vnd.api+json",
@@ -434,7 +494,7 @@ describe Rack::UTF8Sanitizer do
434
494
  end
435
495
 
436
496
  def sanitize_data(request_env = request_env())
437
- @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".force_encoding('UTF-8')
497
+ @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".dup.force_encoding('UTF-8')
438
498
  @response_env = @app.(request_env)
439
499
  sanitized_input = @response_env['rack.input'].read
440
500
 
@@ -508,7 +568,7 @@ describe Rack::UTF8Sanitizer do
508
568
 
509
569
  describe "with only and/or except options" do
510
570
  before do
511
- @plain_input = "foo\xe0".force_encoding('UTF-8')
571
+ @plain_input = "foo\xe0".dup.force_encoding('UTF-8')
512
572
  end
513
573
 
514
574
  def request_env
@@ -565,7 +625,7 @@ describe Rack::UTF8Sanitizer do
565
625
 
566
626
  describe "with custom strategy" do
567
627
  def request_env
568
- @plain_input = "foo bar лол".force_encoding('UTF-8')
628
+ @plain_input = "foo bar лол".dup.force_encoding('UTF-8')
569
629
  {
570
630
  "REQUEST_METHOD" => "POST",
571
631
  "CONTENT_TYPE" => "application/json",
@@ -575,7 +635,7 @@ describe Rack::UTF8Sanitizer do
575
635
  end
576
636
 
577
637
  def sanitize_data(request_env = request_env())
578
- @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".force_encoding('UTF-8')
638
+ @uri_input = "http://bar/foo+%2F%3A+bar+%D0%BB%D0%BE%D0%BB".dup.force_encoding('UTF-8')
579
639
  @response_env = @app.(request_env)
580
640
  sanitized_input = @response_env['rack.input'].read
581
641
 
@@ -609,7 +669,7 @@ describe Rack::UTF8Sanitizer do
609
669
  it "accepts a proc as a strategy" do
610
670
  truncate = -> (input, sanitize_null_bytes:) do
611
671
  sanitize_null_bytes.should == false
612
- 'replace'.force_encoding(Encoding::UTF_8)
672
+ "replace".dup.force_encoding(Encoding::UTF_8)
613
673
  end
614
674
 
615
675
  @app = Rack::UTF8Sanitizer.new(-> env { env }, strategy: truncate)
@@ -628,7 +688,7 @@ describe Rack::UTF8Sanitizer do
628
688
  it "accepts a proc as a strategy and passes along sanitize_null_bytes" do
629
689
  truncate = -> (input, sanitize_null_bytes:) do
630
690
  sanitize_null_bytes.should == true
631
- 'replace'.force_encoding(Encoding::UTF_8)
691
+ "replace".dup.force_encoding(Encoding::UTF_8)
632
692
  end
633
693
 
634
694
  @app = Rack::UTF8Sanitizer.new(-> env { env }, sanitize_null_bytes: true, strategy: truncate)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-utf8_sanitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
- - whitequark
7
+ - Catherine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-05 00:00:00.000000000 Z
11
+ date: 2025-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -93,7 +93,7 @@ files:
93
93
  - lib/rack/utf8_sanitizer.rb
94
94
  - rack-utf8_sanitizer.gemspec
95
95
  - test/test_utf8_sanitizer.rb
96
- homepage: http://github.com/whitequark/rack-utf8_sanitizer
96
+ homepage: https://github.com/whitequark/rack-utf8_sanitizer
97
97
  licenses:
98
98
  - MIT
99
99
  metadata: {}
@@ -105,14 +105,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
- version: 1.9.3
108
+ version: '2.3'
109
109
  required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
113
  version: '0'
114
114
  requirements: []
115
- rubygems_version: 3.2.5
115
+ rubygems_version: 3.3.15
116
116
  signing_key:
117
117
  specification_version: 4
118
118
  summary: Rack::UTF8Sanitizer is a Rack middleware which cleans up invalid UTF8 characters