Skip to content

Commit f463b20

Browse files
Copilotnorthrup
andcommitted
Add input sanitization for semicolon in text evaluation
- Validate primary key value is not empty/nil after semicolon splitting - Strip whitespace from primary key value after splitting - Skip empty parts from trailing/consecutive semicolons - Add test fixtures and test cases for edge cases Co-authored-by: northrup <[email protected]>
1 parent 4ea2247 commit f463b20

5 files changed

Lines changed: 46 additions & 2 deletions

File tree

lib/entitlements/data/groups/calculated/text.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,13 @@ def parsed_predicate(val)
316316
return { key: v } unless v.include?(";")
317317

318318
parts = v.split(/\s*;\s*/)
319-
op_hash = { key: parts.shift }
320-
parts.each do |part|
319+
primary_value = parts.shift
320+
if primary_value.nil? || primary_value.strip.empty?
321+
raise ArgumentError, "Rule Error: Empty value with semicolon predicate in #{filename}!"
322+
end
323+
324+
op_hash = { key: primary_value.strip }
325+
parts.reject { |part| part.strip.empty? }.each do |part|
321326
if part =~ /\A(\w+)\s*=\s*(\S+)\s*\z/
322327
predicate_keyword, predicate_value = Regexp.last_match(1), Regexp.last_match(2)
323328
unless SEMICOLON_PREDICATES.include?(predicate_keyword)

spec/unit/entitlements/data/groups/calculated/text_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,5 +589,38 @@
589589
expect(result).to eq(answer)
590590
end
591591
end
592+
593+
context "with a leading semicolon in the value" do
594+
let(:filename) { fixture("ldap-config/text/leading-semicolon.txt") }
595+
596+
it "raises an error about empty value" do
597+
expect do
598+
subject.send(:parsed_data)
599+
end.to raise_error(ArgumentError, /Rule Error: Empty value with semicolon predicate in .+leading-semicolon.txt!/)
600+
end
601+
end
602+
603+
context "with only a semicolon as the value" do
604+
let(:filename) { fixture("ldap-config/text/only-semicolon.txt") }
605+
606+
it "raises an error about empty value" do
607+
expect do
608+
subject.send(:parsed_data)
609+
end.to raise_error(ArgumentError, /Rule Error: Empty value with semicolon predicate in .+only-semicolon.txt!/)
610+
end
611+
end
612+
613+
context "with a trailing semicolon in the value" do
614+
let(:filename) { fixture("ldap-config/text/trailing-semicolon.txt") }
615+
616+
it "parses correctly ignoring trailing semicolon" do
617+
result = subject.send(:parsed_data)
618+
answer = {
619+
"description" => {"=" => [{ key: "Trailing semicolon test" }], "!=" => [], "&=" => []},
620+
"username" => {"=" => [{ key: "blackmanx" }], "!=" => [], "&=" => []}
621+
}
622+
expect(result).to eq(answer)
623+
end
624+
end
592625
end
593626
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
description = Leading semicolon test
2+
username = ;expiration = 2025-01-01
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
description = Only semicolon test
2+
username = ;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
description = Trailing semicolon test
2+
username = blackmanx;

0 commit comments

Comments
 (0)