Skip to content
Permalink
Browse files Browse the repository at this point in the history
Truncate summaries to 100,000 characters in the query command
This avoids a DOS vector where incredibly large summary strings would hang rubygems due to taking forever in Gem::Text.clean_text
  • Loading branch information
segiddins committed Aug 28, 2017
1 parent 1bcbc7f commit 8a38a4f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/rubygems/commands/query_command.rb
Expand Up @@ -353,7 +353,8 @@ def spec_platforms entry, platforms
end

def spec_summary entry, spec
entry << "\n\n" << format_text(spec.summary, 68, 4)
summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
entry << "\n\n" << format_text(summary, 68, 4)
end

end
6 changes: 6 additions & 0 deletions lib/rubygems/text.rb
Expand Up @@ -13,6 +13,12 @@ def clean_text(text)
text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
end

def truncate_text(text, description, max_length = 100_000)
raise ArgumentError, "max_length must be positive" unless max_length > 0
return text if text.size <= max_length
"Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length]
end

##
# Wraps +text+ to +wrap+ characters and optionally indents by +indent+
# characters
Expand Down
40 changes: 40 additions & 0 deletions test/rubygems/test_gem_commands_query_command.rb
Expand Up @@ -156,6 +156,46 @@ def test_execute_details_cleans_text
This is a lot of text. This is a lot of text. This is a lot of text.
This is a lot of text.
pl (1)
Platform: i386-linux
Author: A User
Homepage: http://example.com
this is a summary
EOF

assert_equal expected, @ui.output
assert_equal '', @ui.error
end

def test_execute_details_truncates_summary
spec_fetcher do |fetcher|
fetcher.spec 'a', 2 do |s|
s.summary = 'This is a lot of text. ' * 10_000
s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
s.homepage = "http://a.example.com/\x03"
end

fetcher.legacy_platform
end

@cmd.handle_options %w[-r -d]

use_ui @ui do
@cmd.execute
end

expected = <<-EOF
*** REMOTE GEMS ***
a (2)
Authors: Abraham Lincoln ., . Hirohito
Homepage: http://a.example.com/.
Truncating the summary for a-2 to 100,000 characters:
#{" This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449} This is a lot of te
pl (1)
Platform: i386-linux
Author: A User
Expand Down
7 changes: 7 additions & 0 deletions test/rubygems/test_gem_text.rb
Expand Up @@ -78,4 +78,11 @@ def test_levenshtein_distance_replace
assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest")
assert_equal 7, levenshtein_distance("zentest", "xxxxxxx")
end

def test_truncate_text
assert_equal "abc", truncate_text("abc", "desc")
assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2)
s = "ab" * 500_001
assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000)
end
end

0 comments on commit 8a38a4f

Please sign in to comment.