File tree Expand file tree Collapse file tree 2 files changed +16
-2
lines changed
Expand file tree Collapse file tree 2 files changed +16
-2
lines changed Original file line number Diff line number Diff line change @@ -16,8 +16,8 @@ def demodulize(path)
1616
1717 def underscore ( camel_cased_word )
1818 camel_cased_word
19- . gsub ( /([A-Z]+)( [A-Z][a-z])/ , '\1_\2' )
20- . gsub ( /([a-z\d ])([A-Z])/ , '\1_\2' )
19+ . gsub ( /(?<= [A-Z])(?= [A-Z][a-z])/ , "_" )
20+ . gsub ( /(?<= [a-z\d ])(?= [A-Z])/ , "_" )
2121 . tr ( "-" , "_" )
2222 . downcase
2323 end
Original file line number Diff line number Diff line change 11# frozen_string_literal: true
22
33require "test_helper"
4+ require "timeout"
45
56module MCP
67 class StringUtilsTest < Minitest ::Test
@@ -18,5 +19,18 @@ def test_handle_from_class_name_returns_the_class_name_without_the_module_for_a_
1819 assert_equal ( "test" , StringUtils . handle_from_class_name ( "Module::Submodule::Test" ) )
1920 assert_equal ( "test_class" , StringUtils . handle_from_class_name ( "Module::Submodule::TestClass" ) )
2021 end
22+
23+ def test_handle_from_class_name_does_not_cause_redos
24+ # A long string of uppercase letters followed by a non-lowercase character
25+ # would trigger catastrophic backtracking with the vulnerable regex patterns.
26+ malicious_input = "A" * 50_000 + "!"
27+
28+ result = nil
29+ Timeout . timeout ( 1 ) do
30+ result = StringUtils . handle_from_class_name ( malicious_input )
31+ end
32+
33+ assert_equal ( "a" * 50_000 + "!" , result )
34+ end
2135 end
2236end
You can’t perform that action at this time.
0 commit comments