rack-utf8_sanitizer 1.9.0 → 1.10.0

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: 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