From ebb0f780b2d6f2cc9f70579d339c04aafa06b8ea Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 16:07:54 +0900 Subject: [PATCH 1/5] Separate each test methods --- test/cgi/test_cgi_session.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb index 32b907d..980ab7d 100644 --- a/test/cgi/test_cgi_session.rb +++ b/test/cgi/test_cgi_session.rb @@ -55,8 +55,8 @@ def test_cgi_session_filestore assert_equal(value1,session["key1"]) assert_equal(value2,session["key2"]) session.close - end + def test_cgi_session_pstore update_env( 'REQUEST_METHOD' => 'GET', @@ -92,6 +92,7 @@ def test_cgi_session_pstore assert_equal(value2,session["key2"]) session.close end if defined?(::PStore) + def test_cgi_session_specify_session_id update_env( 'REQUEST_METHOD' => 'GET', @@ -130,6 +131,7 @@ def test_cgi_session_specify_session_id assert_equal("foo",session.session_id) session.close end + def test_cgi_session_specify_session_key update_env( 'REQUEST_METHOD' => 'GET', From eec721bfe756a1a620ca4159d861ebdc1ca1e7e0 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 24 Apr 2025 19:39:11 +0900 Subject: [PATCH 2/5] Add 'digest' option The option specifies the digest algorithm to hash the session id when generating the filename for this session's FileStore file. It is defaulted to "MD5" because of backward compatibility for now. --- lib/cgi/session.rb | 11 +++++++++-- test/cgi/test_cgi_session.rb | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb index c0a9ae1..5b0ed98 100644 --- a/lib/cgi/session.rb +++ b/lib/cgi/session.rb @@ -210,15 +210,19 @@ def create_new_id # suffix:: the prefix to add to the session id when generating # the filename for this session's FileStore file. # Defaults to the empty string. + # digest:: the digest algorithm to hash the session id when + # generating the filename for this session's FileStore + # file. Defaults to "SHA256". def new_store_file(option={}) # :nodoc: dir = option['tmpdir'] || Dir::tmpdir prefix = option['prefix'] suffix = option['suffix'] + algorithm = option['digest'] || 'SHA256' require 'digest' - sha256 = Digest::SHA256.hexdigest(session_id)[0,16] + digest = Digest(algorithm).hexdigest(session_id)[0,16] path = dir+"/" path << prefix if prefix - path << sha256 + path << digest path << suffix if suffix if File::exist? path hash = nil @@ -410,6 +414,9 @@ class FileStore # suffix:: the prefix to add to the session id when generating # the filename for this session's FileStore file. # Defaults to the empty string. + # digest:: the digest algorithm to hash the session id when + # generating the filename for this session's FileStore + # file. Defaults to "MD5". # # This session's FileStore file will be created if it does # not exist, or opened if it does. diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb index 980ab7d..4d41502 100644 --- a/test/cgi/test_cgi_session.rb +++ b/test/cgi/test_cgi_session.rb @@ -168,4 +168,23 @@ def test_cgi_session_specify_session_key assert_equal(value2,session["key2"]) session.close end + + def test_cgi_session_filestore_digest + session_id = "banana" + path_default = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id) + assert_equal path_default, session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id) + path_sha512 = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>"SHA512") + assert_not_equal path_sha512, path_default + end + + private + + def session_file_store_path(options) + cgi = Object.new + session = CGI::Session.new(cgi, options) + session.delete + dbman = session.instance_variable_get(:@dbman) + assert_kind_of(CGI::Session::FileStore, dbman) + dbman.instance_variable_get(:@path) + end end From 4a723bb024fd32caffa2df7e3b48abaf3aaf6afe Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 12 Dec 2021 17:03:30 +0900 Subject: [PATCH 3/5] Allow digest classes as the digest for store path --- lib/cgi/session.rb | 7 +++++-- test/cgi/test_cgi_session.rb | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb index 5b0ed98..f9b1d0a 100644 --- a/lib/cgi/session.rb +++ b/lib/cgi/session.rb @@ -218,8 +218,11 @@ def new_store_file(option={}) # :nodoc: prefix = option['prefix'] suffix = option['suffix'] algorithm = option['digest'] || 'SHA256' - require 'digest' - digest = Digest(algorithm).hexdigest(session_id)[0,16] + if String === algorithm + require 'digest' + algorithm = Digest(algorithm) + end + digest = algorithm.hexdigest(session_id)[0,16] path = dir+"/" path << prefix if prefix path << digest diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb index 4d41502..a9f49f0 100644 --- a/test/cgi/test_cgi_session.rb +++ b/test/cgi/test_cgi_session.rb @@ -175,6 +175,11 @@ def test_cgi_session_filestore_digest assert_equal path_default, session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id) path_sha512 = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>"SHA512") assert_not_equal path_sha512, path_default + + path = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>Digest::SHA256) + assert_equal path_default, path + path = assert_session_filestore_path(session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>Digest::SHA512)) + assert_equal path_sha512, path end private From b7f2cdc68bb7935b851ff504bd17a40aab8c4971 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 23 Jun 2025 23:27:25 +0900 Subject: [PATCH 4/5] Improve tests --- test/cgi/test_cgi_session.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb index a9f49f0..b37612f 100644 --- a/test/cgi/test_cgi_session.rb +++ b/test/cgi/test_cgi_session.rb @@ -169,11 +169,13 @@ def test_cgi_session_specify_session_key session.close end - def test_cgi_session_filestore_digest + def test_cgi_session_filestore_path session_id = "banana" path_default = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id) + assert_session_filestore_path(path_default) assert_equal path_default, session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id) path_sha512 = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>"SHA512") + assert_session_filestore_path(path_default) assert_not_equal path_sha512, path_default path = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>Digest::SHA256) @@ -184,6 +186,14 @@ def test_cgi_session_filestore_digest private + def assert_session_filestore_path(path, dir: @session_dir, prefix: "cgi_sid_", suffix: nil) + base = File.basename(path) + assert_equal dir, File.dirname(path) + assert_operator base, :start_with?, prefix if prefix + assert_operator base, :end_with?, suffix if suffix + path + end + def session_file_store_path(options) cgi = Object.new session = CGI::Session.new(cgi, options) From c66e0f4d80cc0bf8bc5044a2fda5d4e44140707d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 23 Jun 2025 23:27:40 +0900 Subject: [PATCH 5/5] Add `length` option --- lib/cgi/session.rb | 6 ++++-- test/cgi/test_cgi_session.rb | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb index f9b1d0a..b69857b 100644 --- a/lib/cgi/session.rb +++ b/lib/cgi/session.rb @@ -206,13 +206,15 @@ def create_new_id # on Unix systems). # prefix:: the prefix to add to the session id when generating # the filename for this session's FileStore file. - # Defaults to "cgi_sid_". + # Defaults to the empty string. # suffix:: the prefix to add to the session id when generating # the filename for this session's FileStore file. # Defaults to the empty string. # digest:: the digest algorithm to hash the session id when # generating the filename for this session's FileStore # file. Defaults to "SHA256". + # length:: the length of the session id part of the filestore, + # excluding +prefix+ and +suffix+ parts. Defaults to 16. def new_store_file(option={}) # :nodoc: dir = option['tmpdir'] || Dir::tmpdir prefix = option['prefix'] @@ -222,7 +224,7 @@ def new_store_file(option={}) # :nodoc: require 'digest' algorithm = Digest(algorithm) end - digest = algorithm.hexdigest(session_id)[0,16] + digest = algorithm.hexdigest(session_id)[0, option['length'] || 16] path = dir+"/" path << prefix if prefix path << digest diff --git a/test/cgi/test_cgi_session.rb b/test/cgi/test_cgi_session.rb index b37612f..381c149 100644 --- a/test/cgi/test_cgi_session.rb +++ b/test/cgi/test_cgi_session.rb @@ -177,6 +177,9 @@ def test_cgi_session_filestore_path path_sha512 = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>"SHA512") assert_session_filestore_path(path_default) assert_not_equal path_sha512, path_default + path_long = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "length"=>32) + assert_equal path_default.length+16, path_long.length + assert_send [path_long, :start_with?, path_default] path = session_file_store_path("tmpdir"=>@session_dir, "session_id"=>session_id, "digest"=>Digest::SHA256) assert_equal path_default, path