Skip to content

Commit 9cf2729

Browse files
committed
Fixup for security warnings
Signed-off-by: Dominik Gedon <dominik.gedon@suse.com>
1 parent 8ff55f2 commit 9cf2729

4 files changed

Lines changed: 108 additions & 10 deletions

File tree

lib/tetra/packages/package.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ def cleanup_description(raw, max_length)
5858
clean = clean[0, max_length]
5959

6060
# Remove the last word if it looks cut off (ends in letters, not punctuation)
61-
# Note: This assumes descriptions usually end with punctuation.
61+
# Note: This assumes descriptions usually end with punctuation.
6262
clean = clean.sub(/\s\w+\z/, "")
6363

64-
# Remove ALL trailing dots efficiently (replaces O(N) loop)
65-
clean.sub(/\.+\z/, "")
64+
# Remove ALL trailing dots efficiently (Security Fix for ReDoS)
65+
# Replaces clean.sub(/\.+\z/, "")
66+
clean = clean.chomp(".") while clean.end_with?(".")
67+
68+
clean
6669
end
6770

6871
def to_spec

lib/tetra/version_matcher.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ class VersionMatcher
1010
# by a ., -, _, ~ or space
1111
# returns a [name, version] pair
1212
def split_version(full_name)
13-
# Use non-capturing group (?:...) for the separator part
14-
matches = full_name.match(/\A(.*?)(?:[.\-_ ~,]?([0-9].*))\z/)
15-
16-
if matches && matches.length > 1
17-
[matches[1], matches[2]]
13+
# 1. Match from the start (\A)
14+
# 2. Capture everything that is NOT a digit (ZERO or more times) -> *?
15+
# 3. Handle the optional separator
16+
# 4. Capture the version (MUST start with a digit)
17+
matches = full_name.match(/\A(?<name>[^0-9]*?)(?:[.\-_ ~,]?(?<version>[0-9].*))\z/)
18+
19+
if matches
20+
[matches[:name], matches[:version]]
1821
else
1922
[full_name, nil]
2023
end
@@ -96,7 +99,11 @@ def chunk_distance(my_chunk, their_chunk)
9699

97100
# true for integer strings
98101
def integer?(string)
99-
string.match?(/^[0-9]+$/)
102+
# Faster than regex for simple digit checks
103+
Integer(string, 10)
104+
true
105+
rescue ArgumentError, TypeError
106+
false
100107
end
101108
end
102109
end

spec/lib/fine/package_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,32 @@
6868
end
6969
end
7070
end
71+
72+
describe "cleanup_description" do
73+
it "cleans up a simple description" do
74+
expect(@package.cleanup_description("Simple description.", 50)).to eq("Simple description")
75+
end
76+
77+
it "removes newlines and extra spaces" do
78+
desc = "Line one.\n\nLine two with spaces."
79+
expect(@package.cleanup_description(desc, 100)).to eq("Line one. Line two with spaces")
80+
end
81+
82+
it "truncates long descriptions" do
83+
desc = "This is a very long description that should be truncated here."
84+
# Truncate at 46 chars: "This is a very long description that should be"
85+
# The logic removes " be" because it ends in letters (assumed cut-off)
86+
expect(@package.cleanup_description(desc, 46)).to eq("This is a very long description that should")
87+
end
88+
89+
it "removes trailing dots (ReDoS fix check)" do
90+
expect(@package.cleanup_description("Description...", 50)).to eq("Description")
91+
expect(@package.cleanup_description("Description..........", 50)).to eq("Description")
92+
end
93+
94+
it "handles cut-off words" do
95+
# "This is a descrip" -> "This is a"
96+
expect(@package.cleanup_description("This is a description", 17)).to eq("This is a")
97+
end
98+
end
7199
end

spec/lib/fine/speccable_spec.rb

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77

88
# mock class to test the module
99
class SpeccableTestClass
10-
attr_accessor :world_property
10+
attr_accessor :world_property, :src_archive, :name, :version, :patches,
11+
:artifact_ids, :runtime_dependency_ids, :outputs
1112

1213
include Tetra::Speccable
1314

1415
def initialize
1516
@world_property = "World!"
17+
@name = "test-package"
18+
@version = "1.0"
19+
@src_archive = nil
20+
@patches = []
21+
@artifact_ids = []
22+
@runtime_dependency_ids = []
23+
@outputs = []
1624
end
1725
end
1826

@@ -90,4 +98,56 @@ def initialize
9098
end
9199
end
92100
end
101+
102+
describe "#to_spec unzip requirement" do
103+
before(:each) do
104+
template_content = <<~ERB
105+
Name: <%= name %>
106+
<% if src_archive&.downcase&.end_with?(".zip") %>
107+
BuildRequires: unzip
108+
<% end %>
109+
ERB
110+
File.write(@template_path, template_content)
111+
end
112+
113+
it "adds BuildRequires: unzip if the source is a .zip file" do
114+
instance.src_archive = "sources.zip"
115+
expect(instance._to_spec(@project, "test-package", "test.spec", "output")).to be_truthy
116+
117+
@project.from_directory do
118+
spec_lines = File.readlines(@destination_path)
119+
expect(spec_lines).to include("BuildRequires: unzip\n")
120+
end
121+
end
122+
123+
it "adds BuildRequires: unzip if the source is a .ZIP file (case insensitivity)" do
124+
instance.src_archive = "SOURCES.ZIP"
125+
expect(instance._to_spec(@project, "test-package", "test.spec", "output")).to be_truthy
126+
127+
@project.from_directory do
128+
spec_lines = File.readlines(@destination_path)
129+
expect(spec_lines).to include("BuildRequires: unzip\n")
130+
end
131+
end
132+
133+
it "does not add BuildRequires: unzip if the source is a tarball" do
134+
instance.src_archive = "sources.tar.gz"
135+
expect(instance._to_spec(@project, "test-package", "test.spec", "output")).to be_truthy
136+
137+
@project.from_directory do
138+
spec_lines = File.readlines(@destination_path)
139+
expect(spec_lines).not_to include("BuildRequires: unzip\n")
140+
end
141+
end
142+
143+
it "does not add BuildRequires: unzip if there is no source archive" do
144+
instance.src_archive = nil
145+
expect(instance._to_spec(@project, "test-package", "test.spec", "output")).to be_truthy
146+
147+
@project.from_directory do
148+
spec_lines = File.readlines(@destination_path)
149+
expect(spec_lines).not_to include("BuildRequires: unzip\n")
150+
end
151+
end
152+
end
93153
end

0 commit comments

Comments
 (0)