Skip to content

Commit

Permalink
(PUP-11515) Negative Lookbehind Regex Causes Duplicate Node
Browse files Browse the repository at this point in the history
Before this commit, two nodes could collide due to the lookaround
Regex pattern. This issue arose because the regex was converted to
a regular string by ignoring characters other than a-z, 0-9, _, and -.

For example, /(?<!a)sync/ was converted to "__node_regexp__async,"
and /async/ was also converted to "__node_regexp__async," causing
an error that the node was already defined.

To prevent such duplication, this commit normalize the lookarround
pattern from the regex, ensuring a unique string in case
of lookarround pattern conflict.

For example, /(?<!a)sync/ will converted to "__node_regexp__LPQULTEXaRPsync"
replacing (?<!a) to "LPQULTEXaRP" while converting to the string.
  • Loading branch information
imaqsood committed Jul 31, 2024
1 parent a812d7c commit e9a0388
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
16 changes: 15 additions & 1 deletion lib/puppet/resource/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class Puppet::Resource::Type
DOUBLE_COLON = '::'
EMPTY_ARRAY = [].freeze

LOOKARROUND_OPERATORS = {
"(" => 'LP',
"?" => "QU",
"<" => "LT",
">" => "GT",
"!" => "EX",
"=" => "EQ",
")" => 'RP'
}.freeze

attr_accessor :file, :line, :doc, :code, :parent, :resource_type_collection, :override
attr_reader :namespace, :arguments, :behaves_like, :module_name

Expand Down Expand Up @@ -196,7 +206,11 @@ def instantiate_resource(scope, resource)

def name
if type == :node && name_is_regex?
"__node_regexp__#{@name.source.downcase.gsub(/[^-\w:.]/, '').sub(/^\.+/, '')}"
# Normalize lookarround regex patthern
internal_name = @name.source.downcase.gsub(/\(\?[^)]*\)/) do |str|
str.gsub(/./) { |ch| LOOKARROUND_OPERATORS[ch] || ch }
end
"__node_regexp__#{internal_name.gsub(/[^-\w:.]/, '').sub(/^\.+/, '')}"
else
@name
end
Expand Down
9 changes: 9 additions & 0 deletions spec/integration/parser/node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ class foo {
end.not_to raise_error
end

it 'does not raise an error with 2 regex node names are the same due to lookarround pattern' do
expect do
compile_to_catalog(<<-MANIFEST, Puppet::Node.new("async"))
node /(?<!a)sync/ { }
node /async/ { }
MANIFEST
end.not_to raise_error
end

it 'errors when two nodes with regexes collide after some regex syntax is removed' do
expect do
compile_to_catalog(<<-MANIFEST)
Expand Down

0 comments on commit e9a0388

Please sign in to comment.