CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/spec/constants.rb
Views: 1904
1
2
# Monitor constants created by module loading to ensure that the loads in one example don't interfere with the
3
# assertions in another example.
4
module Metasploit::Framework::Spec::Constants
5
extend ActiveSupport::Autoload
6
7
autoload :Each
8
autoload :Suite
9
10
#
11
# CONSTANTS
12
#
13
14
# Regex parsing loaded module constants
15
LOADED_MODULE_CHILD_CONSTANT_REGEXP = /^Mod(?<unpacked_full_name>[0-9a-f]+)$/
16
# The parent namespace child_constant_name that can have children added when loading modules.
17
PARENT_CONSTANT = Msf::Modules
18
# Constant names under {PARENT_CONSTANT} that can persist between specs because they are part of the loader library
19
# and not dynamically loaded code
20
PERSISTENT_CHILD_CONSTANT_NAMES = %w{
21
Error
22
External
23
Loader
24
Metadata
25
MetasploitClassCompatibilityError
26
Namespace
27
VersionCompatibilityError
28
}.map(&:to_sym)
29
30
# Cleans child constants from {PARENT_CONSTANT}.
31
#
32
# @return [true] if there were leaked constants that were cleaned.
33
# @return [false] if there were no leaked constants.
34
# @see each
35
def self.clean
36
count = each do |child_name|
37
PARENT_CONSTANT.send(:remove_const, child_name)
38
end
39
40
count != 0
41
end
42
43
# Adds actions to `spec` task so that `rake spec` fails if any of the following:
44
#
45
# # `log/leaked-constants.log` exists after printing out the leaked constants.
46
# # Each.configured! is unnecessary in `spec/spec_helper.rb` and should be removed.
47
#
48
# @return [void]
49
def self.define_task
50
Suite.define_task
51
# After Suite as Suite will kill for leaks before Each say it cleaned no leaks in case there are leaks in an
52
# `after(:all)` that {Each} won't catch in its `after(:each)` checks.
53
Each.define_task
54
end
55
56
# Yields each child_constant_name under {PARENT_CONSTANT}.
57
#
58
# @yield [child_name]
59
# @yieldparam child_name [Symbol] name of child_constant_name relative to {PARENT_CONSTANT}.
60
# @yieldreturn [void]
61
# @return [Integer] count
62
def self.each
63
inherit = false
64
count = 0
65
66
child_constant_names = PARENT_CONSTANT.constants(inherit)
67
68
child_constant_names.each do |child_constant_name|
69
unless PERSISTENT_CHILD_CONSTANT_NAMES.include? child_constant_name
70
count += 1
71
yield child_constant_name
72
end
73
end
74
75
count
76
end
77
78
# The module full name for `child_constant_name`
79
#
80
# @param child_constant_name [String] the name of a child constant_name under {PARENT_CONSTANT}.
81
# @return [String] full module name used to load `child_constant_name`.
82
# @return [nil] if `child_constant_name` does not correspond to a loaded module.
83
def self.full_name(child_constant_name)
84
full_name = nil
85
86
match = LOADED_MODULE_CHILD_CONSTANT_REGEXP.match(child_constant_name)
87
88
if match
89
potential_full_name = [match[:unpacked_full_name]].pack('H*')
90
91
module_type, _reference_name = potential_full_name.split('/', 2)
92
93
if Msf::MODULE_TYPES.include? module_type
94
full_name = potential_full_name
95
end
96
end
97
98
full_name
99
end
100
end
101
102