Skip to content

Commit aeb5ae5

Browse files
committed
Merge pull request #612 from lavoiesl/identifier-quoting
Reworked all identifier quoting detections
2 parents 8e24162 + 60838a5 commit aeb5ae5

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

lib/puppet/type/mysql_grant.rb

+17-6
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,24 @@ def initialize(*args)
6060
newproperty(:user) do
6161
desc 'User to operate on.'
6262
validate do |value|
63-
# https://dev.mysql.com/doc/refman/5.1/en/account-names.html
64-
# Regex should problably be more like this: /^[`'"]?[^`'"]*[`'"]?@[`'"]?[\w%\.]+[`'"]?$/
65-
raise(ArgumentError, "Invalid user #{value}") unless value =~ /[\w-]*@[\w%\.:]+/
66-
username = value.split('@')[0]
67-
if username.size > 16
68-
raise ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters'
63+
# http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
64+
# If at least one special char is used, string must be quoted
65+
66+
# http://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions/8057827#8057827
67+
if matches = /^(['`"])((?!\1).)+\1@([\w%\.:]+)$/.match(value)
68+
user_part = matches[2]
69+
host_part = matches[3]
70+
elsif matches = /^([0-9a-zA-Z$_]+)@([\w%\.:]+)$/.match(value)
71+
user_part = matches[1]
72+
host_part = matches[2]
73+
elsif matches = /^(?:(?!['`"]).*)([^0-9a-zA-Z$_]).*@.+$/.match(value)
74+
# does not start with a quote, but contains a special character
75+
raise(ArgumentError, "Database user #{value} must be properly quoted, invalid character: '#{matches[1]}'")
76+
else
77+
raise(ArgumentError, "Invalid database user #{value}")
6978
end
79+
80+
raise(ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters') unless user_part.size <= 16
7081
end
7182
end
7283

lib/puppet/type/mysql_user.rb

+17-8
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,28 @@
1010
desc "The name of the user. This uses the 'username@hostname' or username@hostname."
1111
validate do |value|
1212
# http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
13-
# Regex should problably be more like this: /^[`'"]?[^`'"]*[`'"]?@[`'"]?[\w%\.]+[`'"]?$/
1413
# If at least one special char is used, string must be quoted
15-
raise(ArgumentError, "Database user #{value} must be quotted as it contains special characters") if value =~ /^[^'`"].*[^0-9a-zA-Z$_].*[^'`"]@[\w%\.:]+/
16-
raise(ArgumentError, "Invalid database user #{value}") unless value =~ /^(?:['`"][^'`"]*['`"]|[0-9a-zA-Z$_]*)@[\w%\.:]+/
17-
username = value.split('@')[0]
18-
if not ((username =~ /['"`]*['"`]$/ and username.size <= 18) or username.size <= 16)
19-
raise ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters'
14+
15+
# http://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions/8057827#8057827
16+
if matches = /^(['`"])((?:(?!\1).)+)\1@([\w%\.:]+)$/.match(value)
17+
user_part = matches[2]
18+
host_part = matches[3]
19+
elsif matches = /^([0-9a-zA-Z$_]+)@([\w%\.:]+)$/.match(value)
20+
user_part = matches[1]
21+
host_part = matches[2]
22+
elsif matches = /^(?:(?!['`"]).*)([^0-9a-zA-Z$_]).*@.+$/.match(value)
23+
# does not start with a quote, but contains a special character
24+
raise(ArgumentError, "Database user #{value} must be properly quoted, invalid character: '#{matches[1]}'")
25+
else
26+
raise(ArgumentError, "Invalid database user #{value}")
2027
end
28+
29+
raise(ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters') if user_part.size > 16
2130
end
2231

2332
munge do |value|
24-
user_part, host_part = value.split('@')
25-
"#{user_part}@#{host_part.downcase}"
33+
matches = /^((['`"]?).+\2)@([\w%\.:]+)$/.match(value)
34+
"#{matches[1]}@#{matches[3].downcase}"
2635
end
2736
end
2837

spec/unit/puppet/type/mysql_user_spec.rb

+9-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,15 @@
8181
it 'should fail with an unquotted username with special char' do
8282
expect {
8383
Puppet::Type.type(:mysql_user).new(:name => 'in-valid@localhost', :password_hash => 'pass')
84-
}.to raise_error /Database user in-valid@localhost must be quotted/
84+
}.to raise_error /Database user in-valid@localhost must be properly quoted, invalid character: '-'/
85+
end
86+
end
87+
88+
context 'using "misquoted@localhost' do
89+
it 'should fail with a misquoted username is used' do
90+
expect {
91+
Puppet::Type.type(:mysql_user).new(:name => '"misquoted@localhost', :password_hash => 'pass')
92+
}.to raise_error /Invalid database user "misquoted@localhost/
8593
end
8694
end
8795
end

0 commit comments

Comments
 (0)