puppet-sec-lint 0.1.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +4 -2
- data/.idea/puppet-sec-lint.iml +7 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +14 -1
- data/README.md +36 -17
- data/_config.yml +1 -0
- data/docs/404.html +24 -0
- data/docs/Gemfile +30 -0
- data/docs/Gemfile.lock +275 -0
- data/docs/_config.yml +41 -0
- data/docs/_posts/2021-05-03-welcome-to-jekyll.markdown +25 -0
- data/docs/_site/404.html +71 -0
- data/docs/_site/feed.xml +13 -0
- data/docs/_site/index.html +1 -0
- data/docs/_site/jekyll/update/2021/05/03/welcome-to-jekyll.html +77 -0
- data/docs/hard-coded-credentials.md +17 -0
- data/docs/images/puppet-sec-lint_console.png +0 -0
- data/docs/images/puppet-sec-lint_vscode.png +0 -0
- data/docs/index.md +6 -0
- data/exe/puppet-sec-lint +81 -15
- data/file.pp +77 -0
- data/lib/configurations/configuration.rb +2 -1
- data/lib/configurations/regex_configuration.rb +9 -0
- data/lib/facades/configuration_file_facade.rb +3 -1
- data/lib/facades/configuration_page_facade.rb +6 -0
- data/lib/lol.pp +6 -6
- data/lib/puppet-sec-lint/version.rb +3 -1
- data/lib/rule_engine.rb +15 -3
- data/lib/rules/admin_by_default_rule.rb +33 -0
- data/lib/rules/cyrillic_homograph_attack.rb +27 -0
- data/lib/rules/empty_password_rule.rb +35 -0
- data/lib/rules/hard_coded_credentials_rule.rb +22 -31
- data/lib/rules/invalid_ip_addr_binding_rule.rb +37 -0
- data/lib/rules/no_http_rule.rb +26 -9
- data/lib/rules/rule.rb +72 -0
- data/lib/rules/suspicious_comment_rule.rb +28 -0
- data/lib/rules/use_weak_crypto_algorithms_rule.rb +28 -0
- data/lib/servers/language_server.rb +101 -0
- data/lib/servers/linter_server.rb +52 -0
- data/lib/settings.ini +39 -0
- data/lib/{sin.rb → sin/sin.rb} +6 -1
- data/lib/sin/sin_type.rb +44 -0
- data/lib/test.txt +15 -0
- data/lib/test2.rb +16 -0
- data/lib/test3.rb +32 -0
- data/lib/test_new.rb +19 -0
- data/puppet-sec-lint-0.5.3.gem +0 -0
- data/puppet-sec-lint.gemspec +7 -1
- metadata +139 -6
- data/lib/language_server.rb +0 -78
- data/lib/sin_type.rb +0 -12
@@ -13,7 +13,7 @@ class ConfigurationFileFacade
|
|
13
13
|
when DisplayField[:SelectBox]
|
14
14
|
ini[rule][configuration.id] = configuration.value.join(',')
|
15
15
|
else
|
16
|
-
ini[rule][configuration.id] = configuration.value
|
16
|
+
ini[rule][configuration.id] = configuration.value.to_s
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -32,6 +32,8 @@ class ConfigurationFileFacade
|
|
32
32
|
case configuration.displayfield
|
33
33
|
when DisplayField[:SelectBox]
|
34
34
|
configuration.value = ini[rule][configuration.id].split(',')
|
35
|
+
when DisplayField[:RegexBox]
|
36
|
+
configuration.value = Regexp.new ini[rule][configuration.id]
|
35
37
|
else
|
36
38
|
configuration.value = ini[rule][configuration.id]
|
37
39
|
end
|
@@ -50,6 +50,8 @@ class ConfigurationPageFacade
|
|
50
50
|
return_value+="#{option}\n"
|
51
51
|
end
|
52
52
|
return_value += "</textarea>"
|
53
|
+
when DisplayField[:TextBox], DisplayField[:RegexBox]
|
54
|
+
return_value += "<input type=\"text\" id=\"#{configuration.id}\" name=\"#{configuration.id}\" value=\"#{configuration.value.to_s}\" size=\"#{configuration.value.to_s.length()}\"><br>\n"
|
53
55
|
end
|
54
56
|
|
55
57
|
return_value += "<p style=\"color:gray\">#{configuration.description}</p>\n<br>\n"
|
@@ -71,6 +73,10 @@ class ConfigurationPageFacade
|
|
71
73
|
|
72
74
|
when DisplayField[:SelectBox]
|
73
75
|
configuration.value = new_conf[configuration.id].split(/\r?\n/).delete_if(&:empty?)
|
76
|
+
|
77
|
+
when DisplayField[:RegexBox]
|
78
|
+
configuration.value = Regexp.new new_conf[configuration.id]
|
79
|
+
|
74
80
|
else
|
75
81
|
configuration.value = new_conf[configuration.id]
|
76
82
|
end
|
data/lib/lol.pp
CHANGED
@@ -8,17 +8,17 @@
|
|
8
8
|
# the following code addresses the bug: https://bugs.launchpad.net/keystone/+bug/1472285 .
|
9
9
|
|
10
10
|
class consul_template::service (
|
11
|
-
$
|
12
|
-
$
|
13
|
-
$
|
14
|
-
$
|
11
|
+
$pass = lols(3),
|
12
|
+
$aijoijooiumihhn_password = 'pe-puppet'
|
13
|
+
$admin = 'ceisssesrelometer',
|
14
|
+
$aijoijooiumihhn_password = '(adiyu(guygmin',
|
15
15
|
) {
|
16
16
|
exec { 'network-restart':
|
17
17
|
command => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM release-runner key',
|
18
18
|
path => '/usr/bin:/usr/sbin:/bin:/sbin',
|
19
19
|
refreshonly => true,
|
20
20
|
vmware_md5 => 'LOL',
|
21
|
-
autho => '
|
21
|
+
autho => 'MDi09i09i5',
|
22
22
|
cmd => 'virsh secret-define --file ${secret_xml} && virsh secret-set-value --secret ${rbd_secret_uuid} --base64 $(ceph auth get-key client.${user})',
|
23
23
|
$auth_uri => 'http://127.0.0.1:5000',
|
24
24
|
'bind_address' => '0.0.0.0',
|
@@ -80,4 +80,4 @@ UcXHbA==
|
|
80
80
|
replace => true,
|
81
81
|
require => File['/var/lib/gerrit/.ssh']
|
82
82
|
}
|
83
|
-
}
|
83
|
+
}
|
data/lib/rule_engine.rb
CHANGED
@@ -2,18 +2,30 @@ require 'puppet-lint'
|
|
2
2
|
require_relative 'rules/rule'
|
3
3
|
require_relative 'rules/hard_coded_credentials_rule'
|
4
4
|
require_relative 'rules/no_http_rule'
|
5
|
+
require_relative 'rules/admin_by_default_rule'
|
6
|
+
require_relative 'rules/empty_password_rule'
|
7
|
+
require_relative 'rules/invalid_ip_addr_binding_rule'
|
8
|
+
require_relative 'rules/suspicious_comment_rule'
|
9
|
+
require_relative 'rules/use_weak_crypto_algorithms_rule'
|
10
|
+
require_relative 'rules/cyrillic_homograph_attack'
|
5
11
|
|
6
12
|
|
7
13
|
class RuleEngine
|
8
|
-
@rules=[HardCodedCredentialsRule,NoHTTPRule]
|
14
|
+
@rules=[HardCodedCredentialsRule,NoHTTPRule,AdminByDefaultRule,EmptyPasswordRule,InvalidIPAddrBindingRule,UseWeakCryptoAlgorithmsRule,SuspiciousCommentRule,CyrillicHomographAttack]
|
9
15
|
|
10
16
|
class << self
|
11
17
|
attr_accessor :rules
|
12
18
|
end
|
13
19
|
|
14
20
|
def self.getTokens(code)
|
15
|
-
|
16
|
-
|
21
|
+
begin
|
22
|
+
lexer = PuppetLint::Lexer.new
|
23
|
+
tokens = lexer.tokenise(code)
|
24
|
+
rescue
|
25
|
+
puts "Error in getting tokens from Puppet-Lint"
|
26
|
+
tokens = []
|
27
|
+
end
|
28
|
+
|
17
29
|
return tokens
|
18
30
|
end
|
19
31
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../configurations/list_configuration'
|
2
|
+
|
3
|
+
class AdminByDefaultRule < Rule
|
4
|
+
@name = "Admin by default"
|
5
|
+
|
6
|
+
@credentials = /user|usr|pass(word|_|$)|pwd/
|
7
|
+
|
8
|
+
@credentials_conf = RegexConfiguration.new("Regular expression of words present in credentials", @credentials, "Regular expression of words that if present indicate the existence of a secret.")
|
9
|
+
|
10
|
+
@configurations+=[@credentials_conf]
|
11
|
+
|
12
|
+
def self.AnalyzeTokens(tokens)
|
13
|
+
result = []
|
14
|
+
|
15
|
+
ftokens = self.get_tokens(tokens,'admin')
|
16
|
+
ftokens.each do |token|
|
17
|
+
token_value = token.value.downcase
|
18
|
+
token_type = token.type.to_s
|
19
|
+
if ["EQUALS", "FARROW"].include? token.prev_code_token.type.to_s
|
20
|
+
prev_token = token.prev_code_token
|
21
|
+
left_side = prev_token.prev_code_token
|
22
|
+
if left_side.value.downcase =~ @credentials_conf.value and ["VARIABLE", "NAME"].include? left_side.type.to_s
|
23
|
+
if token_value == 'admin'
|
24
|
+
result.append(Sin.new(SinType::AdminByDefault, left_side.line, left_side.column, token.line, token.column+token_value.length))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
return result
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative '../configurations/list_configuration'
|
2
|
+
|
3
|
+
class CyrillicHomographAttack < Rule
|
4
|
+
@name = "Cyrillic Homograph attack"
|
5
|
+
|
6
|
+
@site_w_cyrillic = /^(http(s)?:\/\/)?.*\p{Cyrillic}+/
|
7
|
+
|
8
|
+
@site_w_cyrillic_conf = RegexConfiguration.new("Regular expression of links with Cyrillic characters", @site_w_cyrillic, "Regular expression of website links that have Cyrillic characters.")
|
9
|
+
|
10
|
+
@configurations+=[@site_w_cyrillic_conf]
|
11
|
+
|
12
|
+
def self.AnalyzeTokens(tokens)
|
13
|
+
result = []
|
14
|
+
|
15
|
+
ftokens = self.filter_tokens(tokens)
|
16
|
+
tokens.each do |token|
|
17
|
+
token_value = token.value.downcase
|
18
|
+
token_type = token.type.to_s
|
19
|
+
if ["STRING", "SSTRING"].include? token_type and token_value =~ @site_w_cyrillic_conf.value
|
20
|
+
result.append(Sin.new(SinType::CyrillicHomographAttack, token.line, token.column, token.line, token.column+token_value.length))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
return result
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../configurations/list_configuration'
|
2
|
+
|
3
|
+
class EmptyPasswordRule < Rule
|
4
|
+
@default_trigger_words = %w[pwd password pass]
|
5
|
+
@password = /pass(word|_|$)|pwd/
|
6
|
+
|
7
|
+
@trigger_words_conf = ListConfiguration.new("List of trigger words", @default_trigger_words, "List of words that identify a password variable")
|
8
|
+
@password_conf = RegexConfiguration.new("Regular expression of password name", @password, "Regular expression of names used for password variables.")
|
9
|
+
|
10
|
+
@configurations+=[@trigger_words_conf, @password_conf]
|
11
|
+
|
12
|
+
@name = "Check empty password"
|
13
|
+
|
14
|
+
def self.AnalyzeTokens(tokens)
|
15
|
+
result = []
|
16
|
+
|
17
|
+
ftokens = self.get_string_tokens(tokens,'')
|
18
|
+
ftokens.each do |token|
|
19
|
+
token_value = token.value.downcase
|
20
|
+
token_type = token.type.to_s
|
21
|
+
if ["EQUALS", "FARROW"].include? token.prev_code_token.type.to_s
|
22
|
+
prev_token = token.prev_code_token
|
23
|
+
left_side = prev_token.prev_code_token
|
24
|
+
if left_side.value.downcase =~ @password_conf.value and ["VARIABLE", "NAME"].include? left_side.type.to_s
|
25
|
+
if token_value == ''
|
26
|
+
result.append(Sin.new(SinType::EmptyPassword, prev_token.line, prev_token.column, token.line, token.column+token_value.length))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
return result
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -1,40 +1,34 @@
|
|
1
1
|
require_relative '../configurations/list_configuration'
|
2
|
+
require_relative '../configurations/regex_configuration'
|
2
3
|
|
3
4
|
class HardCodedCredentialsRule < Rule
|
4
|
-
@
|
5
|
-
@
|
6
|
-
@
|
5
|
+
@not_considered_creds = %w[pe-puppet pe-webserver pe-puppetdb pe-postgres pe-console-services pe-orchestration-services pe-ace-server pe-bolt-server]
|
6
|
+
@invalid_values = %w[undefined unset www-data wwwrun www no yes [] root]
|
7
|
+
@secrets = /user|usr|pass(word|_|$)|pwd|key|secret/
|
8
|
+
@non_secrets = /gpg|path|type|buff|zone|mode|tag|header|scheme|length|guid/
|
9
|
+
|
10
|
+
@not_considered_creds_conf = ListConfiguration.new("List of known words not considered in credentials", @not_considered_creds, "List of words not considered secrets by the community (https://puppet.com/docs/pe/2019.8/what_gets_installed_and_where.html#user_and_group_accounts_installed)")
|
11
|
+
@invalid_values_conf = ListConfiguration.new("List of invalid values in credentials", @invalid_values, "List of words that are not valid in a credential, advised by puppet specialists.")
|
12
|
+
@secrets_conf = RegexConfiguration.new("Regular expression of words present in credentials", @secrets, "Regular expression of words that if present indicate the existence of a secret.")
|
13
|
+
@non_secrets_conf = RegexConfiguration.new("Regular expression of words not present in credentials", @non_secrets, "Regular expression of words that if present discard the existence of a secret.")
|
7
14
|
|
8
15
|
@name = "Hard Coded Credentials"
|
9
|
-
@configurations+=[@
|
16
|
+
@configurations+=[@not_considered_creds_conf, @invalid_values_conf, @secrets_conf, @non_secrets_conf]
|
10
17
|
|
11
18
|
def self.AnalyzeTokens(tokens)
|
12
19
|
result = []
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
nxt_nxt_line = nxt_nxt_token.line
|
26
|
-
if (token_type.eql? 'NAME') || (token_type.eql? 'VARIABLE')
|
27
|
-
# puts "Token type: #{token_type}"
|
28
|
-
if (token_line==nxt_nxt_line)
|
29
|
-
token_valu = indi_token.value.downcase
|
30
|
-
nxt_nxt_val = nxt_nxt_token.value.downcase
|
31
|
-
nxt_nxt_type = nxt_nxt_token.type.to_s ## to handle false positives,
|
32
|
-
|
33
|
-
if (self.TriggerWordInString(token_valu)) && ((nxt_nxt_val.length > 0)) && ((!nxt_nxt_type.eql? 'VARIABLE') && (!token_valu.include? "("))
|
34
|
-
result.append(Sin.new(SinType::HardCodedCred, indi_token.line, indi_token.column, nxt_nxt_token.line, nxt_nxt_token.column+nxt_nxt_token.value.length))
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
21
|
+
ftokens = self.filter_tokens(tokens)
|
22
|
+
ftokens.each do |token|
|
23
|
+
token_value = token.value.downcase
|
24
|
+
token_type = token.type.to_s
|
25
|
+
next_token = token.next_code_token
|
26
|
+
# accepts <VARIABLE> <EQUALS> secret OR <NAME> <FARROW> secret, checks if <VARIABLE> | <NAME> satisfy SECRETS but not satisfy NON_SECRETS
|
27
|
+
if ["VARIABLE", "NAME"].include? token_type and ["EQUALS", "FARROW"].include? next_token.type.to_s and token_value =~ @secrets_conf.value and !(token_value =~ @non_secrets_conf.value)
|
28
|
+
right_side_type = next_token.next_code_token.type.to_s
|
29
|
+
right_side_value = next_token.next_code_token.value.downcase
|
30
|
+
if ["STRING", "SSTRING"].include? right_side_type and right_side_value.length > 1 and !@invalid_values_conf.value.include? right_side_value and !(right_side_value =~ /::|\/|\.|\\/ ) and !@not_considered_creds_conf.value.include? right_side_value
|
31
|
+
result.append(Sin.new(SinType::HardCodedCred, token.line, token.column, next_token.next_code_token.line, next_token.next_code_token.column+right_side_value.length))
|
38
32
|
end
|
39
33
|
end
|
40
34
|
end
|
@@ -42,7 +36,4 @@ class HardCodedCredentialsRule < Rule
|
|
42
36
|
return result
|
43
37
|
end
|
44
38
|
|
45
|
-
def self.TriggerWordInString(string)
|
46
|
-
return @trigger_words_conf.value.any? { |word| string.include?(word) }
|
47
|
-
end
|
48
39
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative '../configurations/list_configuration'
|
2
|
+
|
3
|
+
class InvalidIPAddrBindingRule < Rule
|
4
|
+
@name = "Invalid IP Address Binding"
|
5
|
+
|
6
|
+
@ip_addr_bin_regex = /^((http(s)?:\/\/)?0.0.0.0(:\d{1,5})?)$/
|
7
|
+
|
8
|
+
@ip_addr_bin_regex_conf = RegexConfiguration.new("Regular expression of an invalid IP address", @ip_addr_bin_regex, "Regular expression of an IP address considered invalid or insecure to use.")
|
9
|
+
|
10
|
+
@configurations+=[@ip_addr_bin_regex_conf]
|
11
|
+
|
12
|
+
def self.AnalyzeTokens(tokens)
|
13
|
+
result = []
|
14
|
+
|
15
|
+
ftokens = get_tokens(tokens,"0.0.0.0")
|
16
|
+
ftokens.each do |token|
|
17
|
+
token_value = token.value.downcase
|
18
|
+
token_type = token.type.to_s
|
19
|
+
if ["EQUALS", "FARROW"].include? token.prev_code_token.type.to_s
|
20
|
+
prev_token = token.prev_code_token
|
21
|
+
left_side = prev_token.prev_code_token
|
22
|
+
if token_value =~ @ip_addr_bin_regex_conf.value and ["VARIABLE", "NAME"].include? left_side.type.to_s
|
23
|
+
result.append(Sin.new(SinType::InvalidIPAddrBinding, left_side.line, left_side.column, token.line, token.column+token_value.length))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return result
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.filter_tokens_per_value(tokens, token)
|
32
|
+
ftokens=tokens.find_all do |hash|
|
33
|
+
(hash.type.to_s == 'SSTRING' || hash.type.to_s == 'STRING') and hash.value.downcase.include? token
|
34
|
+
end
|
35
|
+
return ftokens
|
36
|
+
end
|
37
|
+
end
|
data/lib/rules/no_http_rule.rb
CHANGED
@@ -1,19 +1,36 @@
|
|
1
1
|
require_relative '../configurations/list_configuration'
|
2
|
-
require_relative '../sin'
|
3
|
-
require_relative '../sin_type'
|
2
|
+
require_relative '../sin/sin'
|
3
|
+
require_relative '../sin/sin_type'
|
4
4
|
|
5
5
|
class NoHTTPRule < Rule
|
6
|
-
@name="No
|
6
|
+
@name="No HTTPS Connections"
|
7
|
+
|
8
|
+
@resources = %w[apt::source ::apt::source wget::fetch yumrepo yum:: aptly::mirror util::system_package yum::managed_yumrepo]
|
9
|
+
@keywords = %w[backport key download uri mirror]
|
10
|
+
@http = /^http:\/\/.+/
|
11
|
+
@whitelist = [] # Todo:Need to check how is this set up
|
12
|
+
|
13
|
+
@resources_conf = ListConfiguration.new("List of resources that can use HTTP", @resources, "List of resources that are known to not use HTTPS but that validate the transferred content with other secure methods.")
|
14
|
+
@keywords_conf = ListConfiguration.new("List of keywords for URLs", @keywords, "List of keywords that identify hyperlinks that should be analyzed.")
|
15
|
+
@http_conf = RegexConfiguration.new("Regular expression of a normal HTTP address", @http, "Regular expression that identifies the URL of a website using the regular non-secure HTTP protocol.")
|
16
|
+
|
17
|
+
@configurations+=[@resources_conf, @keywords_conf, @http_conf]
|
7
18
|
|
8
19
|
def self.AnalyzeTokens(tokens)
|
9
20
|
result = []
|
10
21
|
|
11
|
-
tokens.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
ptokens = self.filter_resources(tokens, @resources_conf.value)
|
23
|
+
ctokens = self.filter_variables(ptokens, @keywords_conf.value)
|
24
|
+
if @whitelist
|
25
|
+
wtokens = self.filter_whitelist(ctokens)
|
26
|
+
else
|
27
|
+
wtokens = ptokens
|
28
|
+
end
|
29
|
+
wtokens.each do |token|
|
30
|
+
token_value = token.value.downcase
|
31
|
+
token_type = token.type.to_s
|
32
|
+
if (token_value =~ @http_conf.value)
|
33
|
+
result.append(Sin.new(SinType::HttpWithoutTLS, token.line, token.column, token.line, token.column+token_value.length))
|
17
34
|
end
|
18
35
|
end
|
19
36
|
|
data/lib/rules/rule.rb
CHANGED
@@ -14,4 +14,76 @@ class Rule
|
|
14
14
|
puts "Implement this"
|
15
15
|
return
|
16
16
|
end
|
17
|
+
|
18
|
+
def self.get_tokens(tokens, token)
|
19
|
+
ftokens=tokens.find_all do |hash|
|
20
|
+
(hash.type.to_s == 'NAME' || hash.type.to_s == 'VARIABLE' || hash.type.to_s == 'SSTRING' || hash.type.to_s == 'STRING') and hash.value.downcase.include? token
|
21
|
+
end
|
22
|
+
return ftokens
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.filter_tokens(tokens)
|
26
|
+
ftokens=tokens.find_all do |hash|
|
27
|
+
(hash.type.to_s == 'SSTRING' || hash.type.to_s == 'STRING' || hash.type.to_s == 'VARIABLE' || hash.type.to_s == 'NAME')
|
28
|
+
end
|
29
|
+
return ftokens
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.filter_resources(tokens, resources)
|
33
|
+
is_resource = false
|
34
|
+
brackets = 0
|
35
|
+
ftokens=tokens.find_all do |hash|
|
36
|
+
|
37
|
+
if resources.include? hash.value.downcase
|
38
|
+
is_resource = true
|
39
|
+
elsif is_resource and hash.type.to_s == "LBRACE"
|
40
|
+
brackets += 1
|
41
|
+
elsif is_resource and hash.type.to_s == "RBRACE"
|
42
|
+
brackets -=1
|
43
|
+
end
|
44
|
+
|
45
|
+
if is_resource and hash.type.to_s == "RBRACE" and brackets == 0
|
46
|
+
is_resource = false
|
47
|
+
end
|
48
|
+
|
49
|
+
if !is_resource
|
50
|
+
(hash.type.to_s == 'NAME' || hash.type.to_s == 'VARIABLE' || hash.type.to_s == 'SSTRING' || hash.type.to_s == 'STRING')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
return ftokens
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.get_string_tokens(tokens, token)
|
57
|
+
ftokens=tokens.find_all do |hash|
|
58
|
+
(hash.type.to_s == 'SSTRING' || hash.type.to_s == 'STRING') and hash.value.downcase.include? token
|
59
|
+
end
|
60
|
+
return ftokens
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.get_comments(tokens)
|
64
|
+
ftokens=tokens.find_all do |hash|
|
65
|
+
(hash.type.to_s == 'COMMENT' || hash.type.to_s == 'MLCOMMENT' || hash.type.to_s == 'SLASH_COMMENT')
|
66
|
+
end
|
67
|
+
return ftokens
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.filter_whitelist(tokens)
|
71
|
+
ftokens=tokens.find_all do |hash|
|
72
|
+
#!(@whitelist =~ hash.value.downcase)
|
73
|
+
true # TODO: Understand the whitelist
|
74
|
+
end
|
75
|
+
return ftokens
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.filter_variables(tokens, keywords)
|
79
|
+
line = -1
|
80
|
+
kw_regex = Regexp.new keywords.join("|")
|
81
|
+
ftokens=tokens.find_all do |hash|
|
82
|
+
if (hash.type.to_s == 'VARIABLE' || hash.type.to_s == 'NAME') and hash.value.downcase =~ kw_regex
|
83
|
+
line = hash.line
|
84
|
+
elsif hash.line != line
|
85
|
+
hash
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
17
89
|
end
|