summaryrefslogtreecommitdiff
path: root/test/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'test/cgi')
-rw-r--r--test/cgi/test_cgi_cookie.rb121
-rw-r--r--test/cgi/test_cgi_core.rb162
-rw-r--r--test/cgi/test_cgi_header.rb85
-rw-r--r--test/cgi/test_cgi_modruby.rb17
-rw-r--r--test/cgi/test_cgi_multipart.rb124
-rw-r--r--test/cgi/test_cgi_session.rb55
-rw-r--r--test/cgi/test_cgi_tag_helper.rb36
-rw-r--r--test/cgi/test_cgi_util.rb287
-rw-r--r--test/cgi/update_env.rb9
9 files changed, 631 insertions, 265 deletions
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
index c1c6a30e70..eadae45313 100644
--- a/test/cgi/test_cgi_cookie.rb
+++ b/test/cgi/test_cgi_cookie.rb
@@ -1,21 +1,26 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'stringio'
+require_relative 'update_env'
class CGICookieTest < Test::Unit::TestCase
+ include UpdateEnv
def setup
- ENV['REQUEST_METHOD'] = 'GET'
- @str1="\xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93"
+ @environ = {}
+ update_env(
+ 'REQUEST_METHOD' => 'GET',
+ 'SCRIPT_NAME' => nil,
+ )
+ @str1="\xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93".dup
@str1.force_encoding("UTF-8") if defined?(::Encoding)
end
def teardown
- %W[REQUEST_METHOD SCRIPT_NAME].each do |name|
- ENV.delete(name)
- end
+ ENV.update(@environ)
end
@@ -27,20 +32,22 @@ class CGICookieTest < Test::Unit::TestCase
assert_nil(cookie.expires)
assert_equal('', cookie.path)
assert_equal(false, cookie.secure)
+ assert_equal(false, cookie.httponly)
assert_equal("name1=val1&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93; path=", cookie.to_s)
end
def test_cgi_cookie_new_complex
t = Time.gm(2030, 12, 31, 23, 59, 59)
- value = ['val1', '&<>"', "\xA5\xE0\xA5\xB9\xA5\xAB"]
+ value = ['val1', '&<>"', "\xA5\xE0\xA5\xB9\xA5\xAB".dup]
value[2].force_encoding("EUC-JP") if defined?(::Encoding)
cookie = CGI::Cookie.new('name'=>'name1',
'value'=>value,
'path'=>'/cgi-bin/myapp/',
'domain'=>'www.example.com',
'expires'=>t,
- 'secure'=>true
+ 'secure'=>true,
+ 'httponly'=>true
)
assert_equal('name1', cookie.name)
assert_equal(value, cookie.value)
@@ -48,7 +55,29 @@ class CGICookieTest < Test::Unit::TestCase
assert_equal(t, cookie.expires)
assert_equal('/cgi-bin/myapp/', cookie.path)
assert_equal(true, cookie.secure)
- assert_equal('name1=val1&%26%3C%3E%22&%A5%E0%A5%B9%A5%AB; domain=www.example.com; path=/cgi-bin/myapp/; expires=Tue, 31 Dec 2030 23:59:59 GMT; secure', cookie.to_s)
+ assert_equal(true, cookie.httponly)
+ assert_equal('name1=val1&%26%3C%3E%22&%A5%E0%A5%B9%A5%AB; domain=www.example.com; path=/cgi-bin/myapp/; expires=Tue, 31 Dec 2030 23:59:59 GMT; secure; HttpOnly', cookie.to_s)
+ end
+
+
+ def test_cgi_cookie_new_with_domain
+ h = {'name'=>'name1', 'value'=>'value1'}
+ cookie = CGI::Cookie.new(h.merge('domain'=>'a.example.com'))
+ assert_equal('a.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'.example.com'))
+ assert_equal('.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'1.example.com'))
+ assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'-a.example.com'))
+ }
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'a-.example.com'))
+ }
end
@@ -80,9 +109,12 @@ class CGICookieTest < Test::Unit::TestCase
assert_equal(name, cookie.name)
assert_equal(value, cookie.value)
end
- ## ',' separator
- cookie_str = 'name1=val1&val2, name2=val2&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93,_session_id=12345'
+ ## don't allow ',' separator
+ cookie_str = 'name1=val1&val2, name2=val2'
cookies = CGI::Cookie.parse(cookie_str)
+ list = [
+ ['name1', ['val1', 'val2, name2=val2']],
+ ]
list.each do |name, value|
cookie = cookies[name]
assert_equal(name, cookie.name)
@@ -90,6 +122,11 @@ class CGICookieTest < Test::Unit::TestCase
end
end
+ def test_cgi_cookie_parse_not_decode_name
+ cookie_str = "%66oo=baz;foo=bar"
+ cookies = CGI::Cookie.parse(cookie_str)
+ assert_equal({"%66oo" => ["baz"], "foo" => ["bar"]}, cookies)
+ end
def test_cgi_cookie_arrayinterface
cookie = CGI::Cookie.new('name1', 'a', 'b', 'c')
@@ -102,6 +139,70 @@ class CGICookieTest < Test::Unit::TestCase
end
+ def test_cgi_cookie_domain_injection_into_name
+ name = "a=b; domain=example.com;"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_newline_injection_into_name
+ name = "a=b;\r\nLocation: http://example.com#"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_multibyte_injection_into_name
+ name = "a=b;\u3042"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_path
+ name = "name"
+ path = "/; samesite=none"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_domain
+ name = "name"
+ path = "/"
+ domain = "example.jp; samesite=none"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_core.rb b/test/cgi/test_cgi_core.rb
index 171ff7b8bc..f7adb7e99f 100644
--- a/test/cgi/test_cgi_core.rb
+++ b/test/cgi/test_cgi_core.rb
@@ -1,12 +1,15 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'stringio'
+require_relative 'update_env'
class CGICoreTest < Test::Unit::TestCase
-
+ include UpdateEnv
def setup
+ @environ = {}
#@environ = {
# 'SERVER_PROTOCOL' => 'HTTP/1.1',
# 'REQUEST_METHOD' => 'GET',
@@ -15,60 +18,36 @@ class CGICoreTest < Test::Unit::TestCase
#ENV.update(@environ)
end
-
def teardown
- @environ.each do |key, val| ENV.delete(key) end
+ ENV.update(@environ)
$stdout = STDOUT
end
def test_cgi_parse_illegal_query
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'a=111&&b=222&c&d=',
'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
- assert_equal(["a","b","c","d"],cgi.keys.sort) if RUBY_VERSION>="1.9"
+ assert_equal(["a","b","c","d"],cgi.keys.sort)
assert_equal("",cgi["d"])
end
def test_cgi_core_params_GET
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'id=123&id=456&id=&id&str=%40h+%3D%7E+%2F%5E%24%2F',
'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
## cgi[]
assert_equal('123', cgi['id'])
assert_equal('@h =~ /^$/', cgi['str'])
- ## cgi[][], cgi[].first, cgi[].to_ary (obsolete 1.9)
- if RUBY_VERSION<"1.9"
- $stderr = StringIO.new
- begin
- assert_equal('123', cgi['id'][0])
- assert_equal('456', cgi['id'][1])
- assert_equal('', cgi['id'][2])
- assert_nil(cgi['id'][3])
- assert_equal('@h =~ /^$/', cgi['str'][0])
- assert_nil(cgi['str'][1])
- assert_equal('123', cgi['id'].first)
- assert_equal('123', cgi['id'].last) # should be '' ?
- id1, id2, id3 = cgi['id']
- assert_equal(['123', '456', ''], [id1, id2, id3])
- str1, = cgi['str']
- assert_equal('@h =~ /^$/', str1)
- assert_not_same(str1, cgi['str']) # necessary?
- ensure
- $stderr = STDERR
- end
- end
## cgi.params
assert_equal(['123', '456', ''], cgi.params['id'])
assert_equal(['@h =~ /^$/'], cgi.params['str'])
@@ -89,14 +68,13 @@ class CGICoreTest < Test::Unit::TestCase
def test_cgi_core_params_POST
query_str = 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F'
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'POST',
'CONTENT_LENGTH' => query_str.length.to_s,
'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
$stdin = StringIO.new
$stdin << query_str
$stdin.rewind
@@ -110,17 +88,18 @@ class CGICoreTest < Test::Unit::TestCase
## invalid parameter name
assert_equal('', cgi['*notfound*'])
assert_equal([], cgi.params['*notfound*'])
+ ensure
+ $stdin = STDIN
end
def test_cgi_core_params_encoding_check
query_str = 'str=%BE%BE%B9%BE'
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'POST',
'CONTENT_LENGTH' => query_str.length.to_s,
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
$stdin = StringIO.new
$stdin << query_str
$stdin.rewind
@@ -128,11 +107,11 @@ class CGICoreTest < Test::Unit::TestCase
hash={}
cgi = CGI.new(:accept_charset=>"UTF-8"){|key,val|hash[key]=val}
## cgi[]
- assert_equal("\xBE\xBE\xB9\xBE".force_encoding("UTF-8"), cgi['str'])
+ assert_equal("\xBE\xBE\xB9\xBE".dup.force_encoding("UTF-8"), cgi['str'])
## cgi.params
- assert_equal(["\xBE\xBE\xB9\xBE".force_encoding("UTF-8")], cgi.params['str'])
+ assert_equal(["\xBE\xBE\xB9\xBE".dup.force_encoding("UTF-8")], cgi.params['str'])
## accept-charset error
- assert_equal({"str"=>"\xBE\xBE\xB9\xBE".force_encoding("UTF-8")},hash)
+ assert_equal({"str"=>"\xBE\xBE\xB9\xBE".dup.force_encoding("UTF-8")},hash)
$stdin.rewind
assert_raise(CGI::InvalidEncoding) do
@@ -142,24 +121,25 @@ class CGICoreTest < Test::Unit::TestCase
$stdin.rewind
cgi = CGI.new(:accept_charset=>"EUC-JP")
## cgi[]
- assert_equal("\xBE\xBE\xB9\xBE".force_encoding("EUC-JP"), cgi['str'])
+ assert_equal("\xBE\xBE\xB9\xBE".dup.force_encoding("EUC-JP"), cgi['str'])
## cgi.params
- assert_equal(["\xBE\xBE\xB9\xBE".force_encoding("EUC-JP")], cgi.params['str'])
+ assert_equal(["\xBE\xBE\xB9\xBE".dup.force_encoding("EUC-JP")], cgi.params['str'])
else
assert(true)
end
+ ensure
+ $stdin = STDIN
end
def test_cgi_core_cookie
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
assert_not_equal(nil,cgi.cookies)
[ ['_session_id', ['12345'], ],
@@ -177,11 +157,10 @@ class CGICoreTest < Test::Unit::TestCase
def test_cgi_core_maxcontentlength
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'POST',
'CONTENT_LENGTH' => (64 * 1024 * 1024).to_s
- }
- ENV.update(@environ)
+ )
ex = assert_raise(StandardError) do
CGI.new
end
@@ -190,57 +169,16 @@ class CGICoreTest < Test::Unit::TestCase
def test_cgi_core_out
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
- ## jis, euc, sjis string
- jis_str = "\e$B8+$m!\"?M$,%4%_$N$h$&$@\e(B"
+ ## euc string
euc_str = "\270\253\244\355\241\242\277\315\244\254\245\264\245\337\244\316\244\350\244\246\244\300"
- sjis_str = "\214\251\202\353\201A\220l\202\252\203S\203~\202\314\202\346\202\244\202\276"
- if RUBY_VERSION<"1.9"
- ## iso-2022-jp
- options = { 'charset'=>'iso-2022-jp' }
- $stdout = StringIO.new
- cgi.out(options) { euc_str }
- assert_equal('ja', options['language'])
- actual = $stdout.string
- expected = "Content-Type: text/html; charset=iso-2022-jp\r\n" +
- "Content-Length: 28\r\n" +
- "Content-Language: ja\r\n" +
- "\r\n" +
- jis_str
- assert_equal(expected,actual)
- ## euc-jp
- options = { 'charset'=>'EUC-JP' }
- $stdout = StringIO.new
- cgi.out(options) { euc_str }
- assert_equal('ja', options['language'])
- actual = $stdout.string
- expected = "Content-Type: text/html; charset=EUC-JP\r\n" +
- "Content-Length: 22\r\n" +
- "Content-Language: ja\r\n" +
- "\r\n" +
- euc_str
- assert_equal(expected, actual)
- ## shift_jis
- options = { 'charset'=>'Shift_JIS' }
- $stdout = StringIO.new
- cgi.out(options) { euc_str }
- assert_equal('ja', options['language'])
- actual = $stdout.string
- expected = "Content-Type: text/html; charset=Shift_JIS\r\n" +
- "Content-Length: 22\r\n" +
- "Content-Language: ja\r\n" +
- "\r\n" +
- sjis_str
- assert_equal(expected, actual)
- end
## utf8 (not converted)
options = { 'charset'=>'utf8' }
$stdout = StringIO.new
@@ -262,7 +200,7 @@ class CGICoreTest < Test::Unit::TestCase
cgi.out(options) { euc_str }
assert_equal('en', options['language'])
## HEAD method
- ENV['REQUEST_METHOD'] = 'HEAD'
+ update_env('REQUEST_METHOD' => 'HEAD')
options = { 'charset'=>'utf8' }
$stdout = StringIO.new
cgi.out(options) { euc_str }
@@ -275,10 +213,9 @@ class CGICoreTest < Test::Unit::TestCase
def test_cgi_core_print
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
$stdout = StringIO.new
str = "foobar"
@@ -290,10 +227,9 @@ class CGICoreTest < Test::Unit::TestCase
def test_cgi_core_environs
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
##
list1 = %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO
@@ -307,9 +243,8 @@ class CGICoreTest < Test::Unit::TestCase
# list2 = %w[ CONTENT_LENGTH SERVER_PORT ]
## string expected
list1.each do |name|
- @environ[name] = "**#{name}**"
+ update_env(name => "**#{name}**")
end
- ENV.update(@environ)
list1.each do |name|
method = name.sub(/\AHTTP_/, '').downcase
actual = cgi.__send__ method
@@ -317,50 +252,51 @@ class CGICoreTest < Test::Unit::TestCase
assert_equal(expected, actual)
end
## integer expected
- ENV['CONTENT_LENGTH'] = '123'
- ENV['SERVER_PORT'] = '8080'
+ update_env('CONTENT_LENGTH' => '123')
+ update_env('SERVER_PORT' => '8080')
assert_equal(123, cgi.content_length)
assert_equal(8080, cgi.server_port)
## raw cookie
- ENV['HTTP_COOKIE'] = 'name1=val1'
- ENV['HTTP_COOKIE2'] = 'name2=val2'
+ update_env('HTTP_COOKIE' => 'name1=val1')
+ update_env('HTTP_COOKIE2' => 'name2=val2')
assert_equal('name1=val1', cgi.raw_cookie)
assert_equal('name2=val2', cgi.raw_cookie2)
end
- def test_cgi_core_htmltype
- @environ = {
+ def test_cgi_core_htmltype_header
+ update_env(
'REQUEST_METHOD' => 'GET',
- }
- ENV.update(@environ)
+ )
## no htmltype
cgi = CGI.new
assert_raise(NoMethodError) do cgi.doctype end
+ assert_equal("Content-Type: text/html\r\n\r\n",cgi.header)
## html3
cgi = CGI.new('html3')
expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
assert_equal(expected, cgi.doctype)
+ assert_equal("Content-Type: text/html\r\n\r\n",cgi.header)
## html4
cgi = CGI.new('html4')
expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
assert_equal(expected, cgi.doctype)
+ assert_equal("Content-Type: text/html\r\n\r\n",cgi.header)
## html4 transitional
cgi = CGI.new('html4Tr')
expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
assert_equal(expected, cgi.doctype)
+ assert_equal("Content-Type: text/html\r\n\r\n",cgi.header)
## html4 frameset
cgi = CGI.new('html4Fr')
expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
assert_equal(expected, cgi.doctype)
+ assert_equal("Content-Type: text/html\r\n\r\n",cgi.header)
## html5
cgi = CGI.new('html5')
expected = '<!DOCTYPE HTML>'
assert_equal(expected, cgi.doctype)
- # cgi.header not broken
- expected = "Content-Type: text/html\r\n\r\n"
- actual = cgi.header
- assert_equal(expected, actual)
+ assert_match(/^<HEADER><\/HEADER>$/i,cgi.header)
end
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
index 4d458b1a71..ec2f4deb72 100644
--- a/test/cgi/test_cgi_header.rb
+++ b/test/cgi/test_cgi_header.rb
@@ -1,48 +1,51 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'time'
+require_relative 'update_env'
class CGIHeaderTest < Test::Unit::TestCase
+ include UpdateEnv
def setup
- @environ = {
+ @environ = {}
+ update_env(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_METHOD' => 'GET',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
- }
- ENV.update(@environ)
+ )
end
def teardown
- @environ.each do |key, val| ENV.delete(key) end
+ ENV.update(@environ)
end
- def test_cgi_header_simple
+ def test_cgi_http_header_simple
cgi = CGI.new
## default content type
expected = "Content-Type: text/html\r\n\r\n"
- actual = cgi.header
+ actual = cgi.http_header
assert_equal(expected, actual)
## content type specified as string
expected = "Content-Type: text/xhtml; charset=utf8\r\n\r\n"
- actual = cgi.header('text/xhtml; charset=utf8')
+ actual = cgi.http_header('text/xhtml; charset=utf8')
assert_equal(expected, actual)
## content type specified as hash
expected = "Content-Type: image/png\r\n\r\n"
- actual = cgi.header('type'=>'image/png')
+ actual = cgi.http_header('type'=>'image/png')
assert_equal(expected, actual)
## charset specified
expected = "Content-Type: text/html; charset=utf8\r\n\r\n"
- actual = cgi.header('charset'=>'utf8')
+ actual = cgi.http_header('charset'=>'utf8')
assert_equal(expected, actual)
end
- def test_cgi_header_complex
+ def test_cgi_http_header_complex
cgi = CGI.new
options = {
'type' => 'text/xhtml',
@@ -55,7 +58,7 @@ class CGIHeaderTest < Test::Unit::TestCase
'expires' => Time.gm(2000, 1, 23, 12, 34, 56),
'location' => 'http://www.ruby-lang.org/',
}
- expected = "Status: 302 Found\r\n"
+ expected = "Status: 302 Found\r\n".dup
expected << "Server: webrick\r\n"
expected << "Connection: close\r\n"
expected << "Content-Type: text/xhtml; charset=utf8\r\n"
@@ -64,26 +67,22 @@ class CGIHeaderTest < Test::Unit::TestCase
expected << "Expires: Sun, 23 Jan 2000 12:34:56 GMT\r\n"
expected << "location: http://www.ruby-lang.org/\r\n"
expected << "\r\n"
- actual = cgi.header(options)
+ actual = cgi.http_header(options)
assert_equal(expected, actual)
end
- def test_cgi_header_argerr
+ def test_cgi_http_header_argerr
cgi = CGI.new
- #expected = NoMethodError # must be ArgumentError
- if RUBY_VERSION>="1.9.0"
- expected = ArgumentError # for CGIAlt
- else
- expected = NoMethodError # for Ruby1.8
- end
+ expected = ArgumentError
+
assert_raise(expected) do
- cgi.header(nil)
+ cgi.http_header(nil)
end
end
- def test_cgi_header_cookie
+ def test_cgi_http_header_cookie
cgi = CGI.new
cookie1 = CGI::Cookie.new('name1', 'abc', '123')
cookie2 = CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true)
@@ -92,67 +91,67 @@ class CGIHeaderTest < Test::Unit::TestCase
c1 = "Set-Cookie: name1=abc&123; path=\r\n"
c2 = "Set-Cookie: name2=value2; path=; secure\r\n"
## CGI::Cookie object
- actual = cgi.header('cookie'=>cookie1)
+ actual = cgi.http_header('cookie'=>cookie1)
expected = ctype + c1 + sep
assert_equal(expected, actual)
## String
- actual = cgi.header('cookie'=>cookie2.to_s)
+ actual = cgi.http_header('cookie'=>cookie2.to_s)
expected = ctype + c2 + sep
assert_equal(expected, actual)
## Array
- actual = cgi.header('cookie'=>[cookie1, cookie2])
+ actual = cgi.http_header('cookie'=>[cookie1, cookie2])
expected = ctype + c1 + c2 + sep
assert_equal(expected, actual)
## Hash
- actual = cgi.header('cookie'=>{'name1'=>cookie1, 'name2'=>cookie2})
+ actual = cgi.http_header('cookie'=>{'name1'=>cookie1, 'name2'=>cookie2})
expected = ctype + c1 + c2 + sep
assert_equal(expected, actual)
end
- def test_cgi_header_output_cookies
+ def test_cgi_http_header_output_cookies
cgi = CGI.new
## output cookies
cookies = [ CGI::Cookie.new('name1', 'abc', '123'),
CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true),
]
cgi.instance_variable_set('@output_cookies', cookies)
- expected = "Content-Type: text/html; charset=utf8\r\n"
+ expected = "Content-Type: text/html; charset=utf8\r\n".dup
expected << "Set-Cookie: name1=abc&123; path=\r\n"
expected << "Set-Cookie: name2=value2; path=; secure\r\n"
expected << "\r\n"
## header when string
- actual = cgi.header('text/html; charset=utf8')
+ actual = cgi.http_header('text/html; charset=utf8')
assert_equal(expected, actual)
## _header_for_string
- actual = cgi.header('type'=>'text/html', 'charset'=>'utf8')
+ actual = cgi.http_header('type'=>'text/html', 'charset'=>'utf8')
assert_equal(expected, actual)
end
- def test_cgi_header_nph
+ def test_cgi_http_header_nph
time_start = Time.now.to_i
cgi = CGI.new
## 'nph' is true
ENV['SERVER_SOFTWARE'] = 'Apache 2.2.0'
- actual1 = cgi.header('nph'=>true)
+ actual1 = cgi.http_header('nph'=>true)
## when old IIS, NPH-mode is forced
ENV['SERVER_SOFTWARE'] = 'IIS/4.0'
- actual2 = cgi.header
- actual3 = cgi.header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
+ actual2 = cgi.http_header
+ actual3 = cgi.http_header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
## newer IIS doesn't require NPH-mode ## [ruby-dev:30537]
ENV['SERVER_SOFTWARE'] = 'IIS/5.0'
- actual4 = cgi.header
- actual5 = cgi.header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
+ actual4 = cgi.http_header
+ actual5 = cgi.http_header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
time_end = Time.now.to_i
date = /^Date: ([A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d\d:\d\d:\d\d GMT)\r\n/
[actual1, actual2, actual3].each do |actual|
assert_match(date, actual)
- assert_includes(time_start..time_end, date =~ actual && Time.parse($1).to_i)
+ assert_include(time_start..time_end, date =~ actual && Time.parse($1).to_i)
actual.sub!(date, "Date: DATE_IS_REMOVED\r\n")
end
## assertion
- expected = "HTTP/1.1 200 OK\r\n"
+ expected = "HTTP/1.1 200 OK\r\n".dup
expected << "Date: DATE_IS_REMOVED\r\n"
expected << "Server: Apache 2.2.0\r\n"
expected << "Connection: close\r\n"
@@ -164,10 +163,10 @@ class CGIHeaderTest < Test::Unit::TestCase
expected.sub!(/^HTTP\/1.1 200 OK\r\n/, "HTTP/1.1 302 Found\r\n")
expected.sub!(/\r\n\r\n/, "\r\nlocation: http://www.example.com/\r\n\r\n")
assert_equal(expected, actual3)
- expected = "Content-Type: text/html\r\n"
+ expected = "Content-Type: text/html\r\n".dup
expected << "\r\n"
assert_equal(expected, actual4)
- expected = "Status: 302 Found\r\n"
+ expected = "Status: 302 Found\r\n".dup
expected << "Content-Type: text/html\r\n"
expected << "location: http://www.example.com/\r\n"
expected << "\r\n"
@@ -177,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
end
+ def test_cgi_http_header_crlf_injection
+ cgi = CGI.new
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_modruby.rb b/test/cgi/test_cgi_modruby.rb
index b41b9bd007..90132962b5 100644
--- a/test/cgi/test_cgi_modruby.rb
+++ b/test/cgi/test_cgi_modruby.rb
@@ -1,17 +1,20 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
+require_relative 'update_env'
class CGIModrubyTest < Test::Unit::TestCase
+ include UpdateEnv
def setup
- @environ = {
+ @environ = {}
+ update_env(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_METHOD' => 'GET',
#'QUERY_STRING' => 'a=foo&b=bar',
- }
- ENV.update(@environ)
+ )
CGI.class_eval { const_set(:MOD_RUBY, true) }
Apache._reset()
#@cgi = CGI.new
@@ -20,7 +23,7 @@ class CGIModrubyTest < Test::Unit::TestCase
def teardown
- @environ.each do |key, val| ENV.delete(key) end
+ ENV.update(@environ)
CGI.class_eval { remove_const(:MOD_RUBY) }
end
@@ -30,7 +33,7 @@ class CGIModrubyTest < Test::Unit::TestCase
cgi = CGI.new
assert(req._setup_cgi_env_invoked?)
assert(! req._send_http_header_invoked?)
- actual = cgi.header
+ actual = cgi.http_header
assert_equal('', actual)
assert_equal('text/html', req.content_type)
assert(req._send_http_header_invoked?)
@@ -51,7 +54,7 @@ class CGIModrubyTest < Test::Unit::TestCase
}
assert(req._setup_cgi_env_invoked?)
assert(! req._send_http_header_invoked?)
- actual = cgi.header(options)
+ actual = cgi.http_header(options)
assert_equal('', actual)
assert_equal('image/gif', req.content_type)
assert_equal('403 Forbidden', req.status_line)
@@ -71,7 +74,7 @@ class CGIModrubyTest < Test::Unit::TestCase
'status' => '200 OK',
'location' => 'http://www.example.com/',
}
- cgi.header(options)
+ cgi.http_header(options)
assert_equal('200 OK', req.status_line) # should be '302 Found' ?
assert_equal(302, req.status)
assert_equal('http://www.example.com/', req.headers_out['location'])
diff --git a/test/cgi/test_cgi_multipart.rb b/test/cgi/test_cgi_multipart.rb
index e39003d7c3..5e8ec25390 100644
--- a/test/cgi/test_cgi_multipart.rb
+++ b/test/cgi/test_cgi_multipart.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'tempfile'
require 'stringio'
+require_relative 'update_env'
##
@@ -31,7 +33,7 @@ class MultiPart
def initialize(boundary=nil)
@boundary = boundary || create_boundary()
- @buf = ''
+ @buf = ''.dup
@buf.force_encoding(::Encoding::ASCII_8BIT) if defined?(::Encoding)
end
attr_reader :boundary
@@ -44,15 +46,14 @@ class MultiPart
buf << "Content-Disposition: form-data: name=\"#{name}\"#{s}\r\n"
buf << "Content-Type: #{content_type}\r\n" if content_type
buf << "\r\n"
- value = value.dup.force_encoding(::Encoding::ASCII_8BIT) if defined?(::Encoding)
- buf << value
+ buf << value.b
buf << "\r\n"
return self
end
def close
buf = @buf
- @buf = ''
+ @buf = ''.dup
return buf << "--#{boundary}--\r\n"
end
@@ -104,17 +105,26 @@ end
class CGIMultipartTest < Test::Unit::TestCase
+ include UpdateEnv
+
def setup
- ENV['REQUEST_METHOD'] = 'POST'
+ @environ = {}
+ update_env(
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_TYPE' => nil,
+ 'CONTENT_LENGTH' => nil,
+ )
+ @tempfiles = []
end
def teardown
- %w[ REQUEST_METHOD CONTENT_TYPE CONTENT_LENGTH REQUEST_METHOD ].each do |name|
- ENV.delete(name)
- end
+ ENV.update(@environ)
$stdin.close() if $stdin.is_a?(Tempfile)
$stdin = STDIN
+ @tempfiles.each {|t|
+ t.close!
+ }
end
def _prepare(data)
@@ -133,41 +143,50 @@ class CGIMultipartTest < Test::Unit::TestCase
ENV['REQUEST_METHOD'] = 'POST'
## set $stdin
tmpfile = Tempfile.new('test_cgi_multipart')
+ @tempfiles << tmpfile
tmpfile.binmode
tmpfile << input
tmpfile.rewind()
$stdin = tmpfile
end
- def _test_multipart
+ def _test_multipart(cgi_options={})
caller(0).find {|s| s =~ /in `test_(.*?)'/ }
#testname = $1
#$stderr.puts "*** debug: testname=#{testname.inspect}"
_prepare(@data)
- cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ options = {:accept_charset=>"UTF-8"}
+ options.merge! cgi_options
+ cgi = CGI.new(options)
expected_names = @data.collect{|hash| hash[:name] }.sort
assert_equal(expected_names, cgi.params.keys.sort)
threshold = 1024*10
@data.each do |hash|
name = hash[:name]
expected = hash[:value]
- if RUBY_VERSION>="1.9"
- if hash[:filename] #if file
- expected_class = @expected_class || (hash[:value].length < threshold ? StringIO : Tempfile)
- assert(cgi.files.keys.member?(hash[:name]))
- else
- expected_class = String
- assert_equal(expected, cgi[name])
- assert_equal(false,cgi.files.keys.member?(hash[:name]))
- end
- else
+ if hash[:filename] #if file
expected_class = @expected_class || (hash[:value].length < threshold ? StringIO : Tempfile)
+ assert(cgi.files.keys.member?(hash[:name]))
+ else
+ expected_class = String
+ assert_equal(expected, cgi[name])
+ assert_equal(false,cgi.files.keys.member?(hash[:name]))
end
assert_kind_of(expected_class, cgi[name])
assert_equal(expected, cgi[name].read())
assert_equal(hash[:filename] || '', cgi[name].original_filename) #if hash[:filename]
assert_equal(hash[:content_type] || '', cgi[name].content_type) #if hash[:content_type]
end
+ ensure
+ if cgi
+ cgi.params.each {|name, vals|
+ vals.each {|val|
+ if val.kind_of?(Tempfile) && val.path
+ val.close!
+ end
+ }
+ }
+ end
end
@@ -183,7 +202,7 @@ class CGIMultipartTest < Test::Unit::TestCase
@boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
@data = [
{:name=>'hidden1', :value=>'foobar'},
- {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A".dup},
{:name=>'file1', :value=>_read('file1.html'),
:filename=>'file1.html', :content_type=>'text/html'},
{:name=>'image1', :value=>_read('small.png'),
@@ -199,7 +218,7 @@ class CGIMultipartTest < Test::Unit::TestCase
@boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
@data = [
{:name=>'hidden1', :value=>'foobar'},
- {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A".dup},
{:name=>'file1', :value=>_read('file1.html'),
:filename=>'file1.html', :content_type=>'text/html'},
{:name=>'image1', :value=>_read('large.png'),
@@ -227,16 +246,29 @@ class CGIMultipartTest < Test::Unit::TestCase
{:name=>'image1', :value=>_read('large.png'),
:filename=>'large.png', :content_type=>'image/png'}, # large image
]
- original = _set_const(CGI, :MAX_MULTIPART_LENGTH, 2 * 1024)
begin
ex = assert_raise(StandardError) do
- _test_multipart()
+ _test_multipart(:max_multipart_length=>2 * 1024) # set via simple scalar
end
assert_equal("too large multipart data.", ex.message)
ensure
- _set_const(CGI, :MAX_MULTIPART_LENGTH, original)
end
- end if CGI.const_defined?(:MAX_MULTIPART_LENGTH)
+ end
+
+
+ def test_cgi_multipart_maxmultipartlength_lambda
+ @data = [
+ {:name=>'image1', :value=>_read('large.png'),
+ :filename=>'large.png', :content_type=>'image/png'}, # large image
+ ]
+ begin
+ ex = assert_raise(StandardError) do
+ _test_multipart(:max_multipart_length=>lambda{2*1024}) # set via lambda
+ end
+ assert_equal("too large multipart data.", ex.message)
+ ensure
+ end
+ end
def test_cgi_multipart_maxmultipartcount
@@ -270,7 +302,7 @@ class CGIMultipartTest < Test::Unit::TestCase
input2
end
ex = assert_raise(EOFError) do
- RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ CGI.new(:accept_charset=>"UTF-8")
end
assert_equal("bad content body", ex.message)
#
@@ -281,7 +313,7 @@ class CGIMultipartTest < Test::Unit::TestCase
input2
end
ex = assert_raise(EOFError) do
- RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ CGI.new(:accept_charset=>"UTF-8")
end
assert_equal("bad content body", ex.message)
end
@@ -291,15 +323,15 @@ class CGIMultipartTest < Test::Unit::TestCase
@boundary = '(.|\n)*'
@data = [
{:name=>'hidden1', :value=>'foobar'},
- {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A".dup},
{:name=>'file1', :value=>_read('file1.html'),
:filename=>'file1.html', :content_type=>'text/html'},
{:name=>'image1', :value=>_read('small.png'),
:filename=>'small.png', :content_type=>'image/png'}, # small image
]
- @data[1][:value].force_encoding("UTF-8") if RUBY_VERSION>="1.9"
+ @data[1][:value].force_encoding("UTF-8")
_prepare(@data)
- cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ cgi = CGI.new(:accept_charset=>"UTF-8")
assert_equal('file1.html', cgi['file1'].original_filename)
end
@@ -311,9 +343,37 @@ class CGIMultipartTest < Test::Unit::TestCase
{:name=>'foo', :value=>"bar"},
]
_prepare(@data)
- cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ cgi = CGI.new(:accept_charset=>"UTF-8")
assert_equal(cgi['foo'], 'bar')
assert_equal(cgi['file'].read, 'b'*10134)
+ cgi['file'].close! if cgi['file'].kind_of? Tempfile
+ end
+
+ def test_cgi_multipart_without_tempfile
+ assert_in_out_err([], <<-'EOM')
+ require 'cgi'
+ require 'stringio'
+ ENV['REQUEST_METHOD'] = 'POST'
+ ENV['CONTENT_TYPE'] = 'multipart/form-data; boundary=foobar1234'
+ body = <<-BODY.gsub(/\n/, "\r\n")
+--foobar1234
+Content-Disposition: form-data: name=\"name1\"
+
+value1
+--foobar1234
+Content-Disposition: form-data: name=\"file1\"; filename=\"file1.html\"
+Content-Type: text/html
+
+<html>
+<body><p>Hello</p></body>
+</html>
+
+--foobar1234--
+BODY
+ ENV['CONTENT_LENGTH'] = body.size.to_s
+ $stdin = StringIO.new(body)
+ CGI.new
+ EOM
end
###
diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb
index 8bd51776ff..b16b69766e 100644
--- a/test/cgi/test_cgi_session.rb
+++ b/test/cgi/test_cgi_session.rb
@@ -1,33 +1,37 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'
require 'stringio'
require 'tmpdir'
+require_relative 'update_env'
class CGISessionTest < Test::Unit::TestCase
+ include UpdateEnv
+
def setup
+ @environ = {}
@session_dir = Dir.mktmpdir(%w'session dir')
end
def teardown
- @environ.each do |key, val| ENV.delete(key) end
+ ENV.update(@environ)
$stdout = STDOUT
FileUtils.rm_rf(@session_dir)
end
def test_cgi_session_filestore
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
# 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
+ )
value1="value1"
- value2="\x8F\xBC\x8D]"
+ value2="\x8F\xBC\x8D]".dup
value2.force_encoding("SJIS") if defined?(::Encoding)
- ENV.update(@environ)
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
session["key1"]=value1
@@ -38,14 +42,13 @@ class CGISessionTest < Test::Unit::TestCase
$stdout = StringIO.new
cgi.out{""}
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'HTTP_COOKIE' => "_session_id=#{session_id}",
'QUERY_STRING' => "_session_id=#{session.session_id}",
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
$stdout = StringIO.new
@@ -55,17 +58,16 @@ class CGISessionTest < Test::Unit::TestCase
end
def test_cgi_session_pstore
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
# 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
+ )
value1="value1"
- value2="\x8F\xBC\x8D]"
+ value2="\x8F\xBC\x8D]".dup
value2.force_encoding("SJIS") if defined?(::Encoding)
- ENV.update(@environ)
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
session["key1"]=value1
@@ -76,14 +78,13 @@ class CGISessionTest < Test::Unit::TestCase
$stdout = StringIO.new
cgi.out{""}
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'HTTP_COOKIE' => "_session_id=#{session_id}",
'QUERY_STRING' => "_session_id=#{session.session_id}",
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
$stdout = StringIO.new
@@ -92,17 +93,16 @@ class CGISessionTest < Test::Unit::TestCase
session.close
end
def test_cgi_session_specify_session_id
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
# 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
+ )
value1="value1"
- value2="\x8F\xBC\x8D]"
+ value2="\x8F\xBC\x8D]".dup
value2.force_encoding("SJIS") if defined?(::Encoding)
- ENV.update(@environ)
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_id"=>"foo")
session["key1"]=value1
@@ -115,14 +115,13 @@ class CGISessionTest < Test::Unit::TestCase
$stdout = StringIO.new
cgi.out{""}
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'HTTP_COOKIE' => "_session_id=#{session_id}",
'QUERY_STRING' => "_session_id=#{session.session_id}",
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
$stdout = StringIO.new
@@ -132,17 +131,16 @@ class CGISessionTest < Test::Unit::TestCase
session.close
end
def test_cgi_session_specify_session_key
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
# 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
# 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
+ )
value1="value1"
- value2="\x8F\xBC\x8D]"
+ value2="\x8F\xBC\x8D]".dup
value2.force_encoding("SJIS") if defined?(::Encoding)
- ENV.update(@environ)
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
session["key1"]=value1
@@ -154,14 +152,13 @@ class CGISessionTest < Test::Unit::TestCase
$stdout = StringIO.new
cgi.out{""}
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
'HTTP_COOKIE' => "bar=#{session_id}",
# 'QUERY_STRING' => "bar=#{session.session_id}",
'SERVER_SOFTWARE' => 'Apache 2.2.0',
'SERVER_PROTOCOL' => 'HTTP/1.1',
- }
- ENV.update(@environ)
+ )
cgi = CGI.new
session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
$stdout = StringIO.new
diff --git a/test/cgi/test_cgi_tag_helper.rb b/test/cgi/test_cgi_tag_helper.rb
index 29306578b0..0b99dfc1bc 100644
--- a/test/cgi/test_cgi_tag_helper.rb
+++ b/test/cgi/test_cgi_tag_helper.rb
@@ -1,12 +1,16 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'stringio'
+require_relative 'update_env'
class CGITagHelperTest < Test::Unit::TestCase
+ include UpdateEnv
def setup
+ @environ = {}
#@environ = {
# 'SERVER_PROTOCOL' => 'HTTP/1.1',
# 'REQUEST_METHOD' => 'GET',
@@ -17,16 +21,15 @@ class CGITagHelperTest < Test::Unit::TestCase
def teardown
- @environ.each do |key, val| ENV.delete(key) end
+ ENV.update(@environ)
$stdout = STDOUT
end
def test_cgi_tag_helper_html3
- @environ = {
+ update_env(
'REQUEST_METHOD' => 'GET',
- }
- ENV.update(@environ)
+ )
## html3
cgi = CGI.new('html3')
assert_equal('<A HREF=""></A>',cgi.a)
@@ -318,13 +321,11 @@ class CGITagHelperTest < Test::Unit::TestCase
assert_match(/^<INPUT .*TYPE="checkbox".*>bb<INPUT .*TYPE="checkbox".*>dd$/,str)
assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
assert_match(/^<INPUT .*>bb<INPUT .*CHECKED.*>dd$/,str)
- assert_match(/<INPUT .*TYPE="text".*>/,cgi.text_field(:name=>"name",:value=>"value")) if RUBY_VERSION>="1.9"
- if RUBY_VERSION>="1.9"
- str=cgi.radio_group("foo",["aa","bb"],["cc","dd",false])
- assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
- assert_match(/^<INPUT .*TYPE="radio".*>bb<INPUT .*TYPE="radio".*>dd$/,str)
- assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
- end
+ assert_match(/<INPUT .*TYPE="text".*>/,cgi.text_field(:name=>"name",:value=>"value"))
+ str=cgi.radio_group("foo",["aa","bb"],["cc","dd",false])
+ assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
+ assert_match(/^<INPUT .*TYPE="radio".*>bb<INPUT .*TYPE="radio".*>dd$/,str)
+ assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
end
=begin
@@ -338,4 +339,17 @@ class CGITagHelperTest < Test::Unit::TestCase
end
=end
+ def test_cgi_tag_helper_html5
+ update_env(
+ 'REQUEST_METHOD' => 'GET',
+ )
+ ## html5
+ cgi = CGI.new('html5')
+ assert_equal('<HEADER></HEADER>',cgi.header)
+ assert_equal('<FOOTER></FOOTER>',cgi.footer)
+ assert_equal('<ARTICLE></ARTICLE>',cgi.article)
+ assert_equal('<SECTION></SECTION>',cgi.section)
+ assert_equal('<!DOCTYPE HTML><HTML BLA="TEST"></HTML>',cgi.html("BLA"=>"TEST"){})
+ end
+
end
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index 2c003a0300..d058cccd86 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -1,64 +1,303 @@
+# frozen_string_literal: true
require 'test/unit'
require 'cgi'
require 'stringio'
+require_relative 'update_env'
class CGIUtilTest < Test::Unit::TestCase
-
+ include CGI::Util
+ include UpdateEnv
def setup
- ENV['REQUEST_METHOD'] = 'GET'
- @str1="&<>\" \xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93"
+ @environ = {}
+ update_env(
+ 'REQUEST_METHOD' => 'GET',
+ 'SCRIPT_NAME' => nil,
+ )
+ @str1="&<>\" \xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93".dup
@str1.force_encoding("UTF-8") if defined?(::Encoding)
end
def teardown
- %W[REQUEST_METHOD SCRIPT_NAME].each do |name|
- ENV.delete(name)
- end
+ ENV.update(@environ)
end
-
def test_cgi_escape
- assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI::escape(@str1))
- assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI::escape(@str1).ascii_only?) if defined?(::Encoding)
+ assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escape(@str1))
+ assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI.escape(@str1).ascii_only?) if defined?(::Encoding)
+ end
+
+ def test_cgi_escape_with_unreserved_characters
+ assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
+ CGI.escape("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"),
+ "should not escape any unreserved characters, as per RFC3986 Section 2.3")
end
def test_cgi_escape_with_invalid_byte_sequence
- assert_nothing_raised(ArgumentError) do
- assert_equal('%C0%3C%3C', CGI::escape("\xC0<<".force_encoding("UTF-8")))
- end
+ assert_equal('%C0%3C%3C', CGI.escape("\xC0\<\<".dup.force_encoding("UTF-8")))
end
def test_cgi_escape_preserve_encoding
- assert_equal(Encoding::US_ASCII, CGI::escape("\xC0<<".force_encoding("US-ASCII")).encoding)
- assert_equal(Encoding::ASCII_8BIT, CGI::escape("\xC0<<".force_encoding("ASCII-8BIT")).encoding)
- assert_equal(Encoding::UTF_8, CGI::escape("\xC0<<".force_encoding("UTF-8")).encoding)
+ assert_equal(Encoding::US_ASCII, CGI.escape("\xC0\<\<".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.escape("\xC0\<\<".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.escape("\xC0\<\<".dup.force_encoding("UTF-8")).encoding)
end
def test_cgi_unescape
- assert_equal(@str1, CGI::unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'))
- assert_equal(@str1.encoding, CGI::unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93').encoding) if defined?(::Encoding)
+ str = CGI.unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ return unless defined?(::Encoding)
+
+ assert_equal(@str1.encoding, str.encoding)
assert_equal("\u{30E1 30E2 30EA 691C 7D22}", CGI.unescape("\u{30E1 30E2 30EA}%E6%A4%9C%E7%B4%A2"))
end
def test_cgi_unescape_preserve_encoding
- assert_equal(Encoding::US_ASCII, CGI::unescape("%C0%3C%3C".force_encoding("US-ASCII")).encoding)
- assert_equal(Encoding::ASCII_8BIT, CGI::unescape("%C0%3C%3C".force_encoding("ASCII-8BIT")).encoding)
- assert_equal(Encoding::UTF_8, CGI::unescape("%C0%3C%3C".force_encoding("UTF-8")).encoding)
+ assert_equal(Encoding::US_ASCII, CGI.unescape("%C0%3C%3C".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.unescape("%C0%3C%3C".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.unescape("%C0%3C%3C".dup.force_encoding("UTF-8")).encoding)
+ end
+
+ def test_cgi_unescape_accept_charset
+ return unless defined?(::Encoding)
+
+ assert_raise(TypeError) {CGI.unescape('', nil)}
+ assert_separately(%w[-rcgi/util], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ assert_equal("", CGI.unescape(''))
+ end;
+ end
+
+ def test_cgi_escapeURIComponent
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escapeURIComponent(@str1))
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI.escapeURIComponent(@str1).ascii_only?) if defined?(::Encoding)
+ end
+
+ def test_cgi_escapeURIComponent_with_unreserved_characters
+ assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
+ CGI.escapeURIComponent("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"),
+ "should not encode any unreserved characters, as per RFC3986 Section 2.3")
+ end
+
+ def test_cgi_escapeURIComponent_with_invalid_byte_sequence
+ assert_equal('%C0%3C%3C', CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("UTF-8")))
+ end
+
+ def test_cgi_escapeURIComponent_preserve_encoding
+ assert_equal(Encoding::US_ASCII, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("UTF-8")).encoding)
+ end
+
+ def test_cgi_unescapeURIComponent
+ str = CGI.unescapeURIComponent('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ return unless defined?(::Encoding)
+
+ assert_equal("foo+bar", CGI.unescapeURIComponent("foo+bar"))
+
+ assert_equal(@str1.encoding, str.encoding)
+ assert_equal("\u{30E1 30E2 30EA 691C 7D22}", CGI.unescapeURIComponent("\u{30E1 30E2 30EA}%E6%A4%9C%E7%B4%A2"))
+ end
+
+ def test_cgi_unescapeURIComponent_preserve_encoding
+ assert_equal(Encoding::US_ASCII, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("UTF-8")).encoding)
+ end
+
+ def test_cgi_unescapeURIComponent_accept_charset
+ return unless defined?(::Encoding)
+
+ assert_raise(TypeError) {CGI.unescapeURIComponent('', nil)}
+ assert_separately(%w[-rcgi/util], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ assert_equal("", CGI.unescapeURIComponent(''))
+ end;
end
def test_cgi_pretty
- assert_equal("<HTML>\n <BODY>\n </BODY>\n</HTML>\n",CGI::pretty("<HTML><BODY></BODY></HTML>"))
- assert_equal("<HTML>\n\t<BODY>\n\t</BODY>\n</HTML>\n",CGI::pretty("<HTML><BODY></BODY></HTML>","\t"))
+ assert_equal("<HTML>\n <BODY>\n </BODY>\n</HTML>\n",CGI.pretty("<HTML><BODY></BODY></HTML>"))
+ assert_equal("<HTML>\n\t<BODY>\n\t</BODY>\n</HTML>\n",CGI.pretty("<HTML><BODY></BODY></HTML>","\t"))
end
def test_cgi_escapeHTML
- assert_equal(CGI::escapeHTML("'&\"><"),"&#39;&amp;&quot;&gt;&lt;")
+ assert_equal("&#39;&amp;&quot;&gt;&lt;", CGI.escapeHTML("'&\"><"))
+ end
+
+ def test_cgi_escape_html_duplicated
+ orig = "Ruby".dup.force_encoding("US-ASCII")
+ str = CGI.escapeHTML(orig)
+ assert_equal(orig, str)
+ assert_not_same(orig, str)
+ end
+
+ def assert_cgi_escape_html_preserve_encoding(str, encoding)
+ assert_equal(encoding, CGI.escapeHTML(str.dup.force_encoding(encoding)).encoding)
+ end
+
+ def test_cgi_escape_html_preserve_encoding
+ Encoding.list do |enc|
+ assert_cgi_escape_html_preserve_encoding("'&\"><", enc)
+ assert_cgi_escape_html_preserve_encoding("Ruby", enc)
+ end
+ end
+
+ def test_cgi_escape_html_dont_freeze
+ assert_not_predicate CGI.escapeHTML("'&\"><".dup), :frozen?
+ assert_not_predicate CGI.escapeHTML("'&\"><".freeze), :frozen?
+ assert_not_predicate CGI.escapeHTML("Ruby".dup), :frozen?
+ assert_not_predicate CGI.escapeHTML("Ruby".freeze), :frozen?
+ end
+
+ def test_cgi_escape_html_large
+ return if RUBY_ENGINE == 'jruby'
+ ulong_max, size_max = RbConfig::LIMITS.values_at("ULONG_MAX", "SIZE_MAX")
+ return unless ulong_max < size_max # Platforms not concerned
+
+ size = (ulong_max / 6 + 1)
+ begin
+ str = '"' * size
+ escaped = CGI.escapeHTML(str)
+ rescue NoMemoryError
+ omit "Not enough memory"
+ rescue => e
+ end
+ assert_raise_with_message(ArgumentError, /overflow/, ->{"length = #{escaped.length}"}) do
+ raise e if e
+ end
end
def test_cgi_unescapeHTML
- assert_equal(CGI::unescapeHTML("&#39;&amp;&quot;&gt;&lt;"),"'&\"><")
+ assert_equal("'&\"><", CGI.unescapeHTML("&#39;&amp;&quot;&gt;&lt;"))
end
+ def test_cgi_unescapeHTML_invalid
+ assert_equal('&<&amp>&quot&abcdefghijklmn', CGI.unescapeHTML('&&lt;&amp&gt;&quot&abcdefghijklmn'))
+ end
+
+ Encoding.list.each do |enc|
+ begin
+ escaped = "&#39;&amp;&quot;&gt;&lt;".encode(enc)
+ unescaped = "'&\"><".encode(enc)
+ rescue Encoding::ConverterNotFoundError
+ next
+ else
+ define_method("test_cgi_escapeHTML:#{enc.name}") do
+ assert_equal(escaped, CGI.escapeHTML(unescaped))
+ end
+ define_method("test_cgi_unescapeHTML:#{enc.name}") do
+ assert_equal(unescaped, CGI.unescapeHTML(escaped))
+ end
+ end
+ end
+
+ Encoding.list.each do |enc|
+ next unless enc.ascii_compatible?
+ begin
+ escaped = "%25+%2B"
+ unescaped = "% +".encode(enc)
+ rescue Encoding::ConverterNotFoundError
+ next
+ else
+ define_method("test_cgi_escape:#{enc.name}") do
+ assert_equal(escaped, CGI.escape(unescaped))
+ end
+ define_method("test_cgi_unescape:#{enc.name}") do
+ assert_equal(unescaped, CGI.unescape(escaped, enc))
+ end
+ end
+ end
+
+ def test_cgi_unescapeHTML_uppercasecharacter
+ assert_equal("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86", CGI.unescapeHTML("&#x3042;&#x3044;&#X3046;"))
+ end
+
+ def test_cgi_include_escape
+ assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93', escape(@str1))
+ end
+
+ def test_cgi_include_escapeHTML
+ assert_equal("&#39;&amp;&quot;&gt;&lt;", escapeHTML("'&\"><"))
+ end
+
+ def test_cgi_include_h
+ assert_equal("&#39;&amp;&quot;&gt;&lt;", h("'&\"><"))
+ end
+
+ def test_cgi_include_unescape
+ str = unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ return unless defined?(::Encoding)
+
+ assert_equal(@str1.encoding, str.encoding)
+ assert_equal("\u{30E1 30E2 30EA 691C 7D22}", unescape("\u{30E1 30E2 30EA}%E6%A4%9C%E7%B4%A2"))
+ end
+
+ def test_cgi_include_unescapeHTML
+ assert_equal("'&\"><", unescapeHTML("&#39;&amp;&quot;&gt;&lt;"))
+ end
+
+ def test_cgi_escapeElement
+ assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<BR><A HREF="url"></A>', "A", "IMG"))
+ assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]))
+ assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', "A", "IMG"))
+ assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', ["A", "IMG"]))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', "A", "IMG"))
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', ["A", "IMG"]))
+ end
+
+
+ def test_cgi_unescapeElement
+ assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescapeElement(escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescapeElement(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
+ assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), ["A", "IMG"]))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), ["A", "IMG"]))
+ end
+end
+
+class CGIUtilPureRubyTest < Test::Unit::TestCase
+ def setup
+ CGI::Escape.module_eval do
+ alias _escapeHTML escapeHTML
+ remove_method :escapeHTML
+ alias _unescapeHTML unescapeHTML
+ remove_method :unescapeHTML
+ end
+ end
+
+ def teardown
+ CGI::Escape.module_eval do
+ alias escapeHTML _escapeHTML
+ remove_method :_escapeHTML
+ alias unescapeHTML _unescapeHTML
+ remove_method :_unescapeHTML
+ end
+ end
+
+ def test_cgi_escapeHTML_with_invalid_byte_sequence
+ assert_equal("&lt;\xA4??&gt;", CGI.escapeHTML(%[<\xA4??>]))
+ end
+
+ def test_cgi_unescapeHTML_with_invalid_byte_sequence
+ input = "\xFF&"
+ assert_equal(input, CGI.unescapeHTML(input))
+ end
end
diff --git a/test/cgi/update_env.rb b/test/cgi/update_env.rb
new file mode 100644
index 0000000000..cbc8dc13c6
--- /dev/null
+++ b/test/cgi/update_env.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: false
+module UpdateEnv
+ def update_env(environ)
+ environ.each do |key, val|
+ @environ[key] = ENV[key] unless @environ.key?(key)
+ ENV[key] = val
+ end
+ end
+end