Skip to content

Commit fa87807

Browse files
authored
Merge pull request #3503 from jake-the-dev/coverage-improvements
Test coverage improvements - Core
2 parents d92d745 + 6469081 commit fa87807

39 files changed

Lines changed: 3267 additions & 409 deletions

core/filters/browser.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Filters
88
# Check the browser type value - for example, 'FF'
99
# @param [String] str String for testing
1010
# @return [Boolean] If the string has valid browser name characters
11-
def self.is_valid_browsername?(str)
11+
def self.is_valid_browsername?(str) # rubocop:disable Naming/PredicatePrefix
1212
return false unless is_non_empty_string?(str)
1313
return false if str.length > 2
1414
return false if has_non_printable_char?(str)
@@ -19,7 +19,7 @@ def self.is_valid_browsername?(str)
1919
# Check the Operating System name value - for example, 'Windows XP'
2020
# @param [String] str String for testing
2121
# @return [Boolean] If the string has valid Operating System name characters
22-
def self.is_valid_osname?(str)
22+
def self.is_valid_osname?(str) # rubocop:disable Naming/PredicatePrefix
2323
return false unless is_non_empty_string?(str)
2424
return false if has_non_printable_char?(str)
2525
return false if str.length < 2
@@ -30,7 +30,7 @@ def self.is_valid_osname?(str)
3030
# Check the Hardware name value - for example, 'iPhone'
3131
# @param [String] str String for testing
3232
# @return [Boolean] If the string has valid Hardware name characters
33-
def self.is_valid_hwname?(str)
33+
def self.is_valid_hwname?(str) # rubocop:disable Naming/PredicatePrefix
3434
return false unless is_non_empty_string?(str)
3535
return false if has_non_printable_char?(str)
3636
return false if str.length < 2
@@ -41,12 +41,12 @@ def self.is_valid_hwname?(str)
4141
# Verify the browser version string is valid
4242
# @param [String] str String for testing
4343
# @return [Boolean] If the string has valid browser version characters
44-
def self.is_valid_browserversion?(str)
44+
def self.is_valid_browserversion?(str) # rubocop:disable Naming/PredicatePrefix
4545
return false unless is_non_empty_string?(str)
4646
return false if has_non_printable_char?(str)
4747
return true if str.eql? 'UNKNOWN'
4848
return true if str.eql? 'ALL'
49-
return false if !nums_only?(str) and !str.match(/\A(0|[1-9][0-9]{0,3})(\.(0|[1-9][0-9]{0,3})){0,3}\z/)
49+
return false if !nums_only?(str) && !str.match(/\A(0|[1-9][0-9]{0,3})(\.(0|[1-9][0-9]{0,3})){0,3}\z/)
5050
return false if str.length > 20
5151

5252
true
@@ -55,7 +55,7 @@ def self.is_valid_browserversion?(str)
5555
# Verify the os version string is valid
5656
# @param [String] str String for testing
5757
# @return [Boolean] If the string has valid os version characters
58-
def self.is_valid_osversion?(str)
58+
def self.is_valid_osversion?(str) # rubocop:disable Naming/PredicatePrefix
5959
return false unless is_non_empty_string?(str)
6060
return false if has_non_printable_char?(str)
6161
return true if str.eql? 'UNKNOWN'
@@ -69,7 +69,7 @@ def self.is_valid_osversion?(str)
6969
# Verify the browser/UA string is valid
7070
# @param [String] str String for testing
7171
# @return [Boolean] If the string has valid browser / ua string characters
72-
def self.is_valid_browserstring?(str)
72+
def self.is_valid_browserstring?(str) # rubocop:disable Naming/PredicatePrefix
7373
return false unless is_non_empty_string?(str)
7474
return false if has_non_printable_char?(str)
7575
return false if str.length > 300
@@ -80,7 +80,7 @@ def self.is_valid_browserstring?(str)
8080
# Verify the cookies are valid
8181
# @param [String] str String for testing
8282
# @return [Boolean] If the string has valid cookie characters
83-
def self.is_valid_cookies?(str)
83+
def self.is_valid_cookies?(str) # rubocop:disable Naming/PredicatePrefix
8484
return false unless is_non_empty_string?(str)
8585
return false if has_non_printable_char?(str)
8686
return false if str.length > 2000
@@ -91,7 +91,7 @@ def self.is_valid_cookies?(str)
9191
# Verify the system platform is valid
9292
# @param [String] str String for testing
9393
# @return [Boolean] If the string has valid system platform characters
94-
def self.is_valid_system_platform?(str)
94+
def self.is_valid_system_platform?(str) # rubocop:disable Naming/PredicatePrefix
9595
return false unless is_non_empty_string?(str)
9696
return false if has_non_printable_char?(str)
9797
return false if str.length > 200
@@ -102,7 +102,7 @@ def self.is_valid_system_platform?(str)
102102
# Verify the date stamp is valid
103103
# @param [String] str String for testing
104104
# @return [Boolean] If the string has valid date stamp characters
105-
def self.is_valid_date_stamp?(str)
105+
def self.is_valid_date_stamp?(str) # rubocop:disable Naming/PredicatePrefix
106106
return false unless is_non_empty_string?(str)
107107
return false if has_non_printable_char?(str)
108108
return false if str.length > 200
@@ -113,7 +113,7 @@ def self.is_valid_date_stamp?(str)
113113
# Verify the CPU type string is valid
114114
# @param [String] str String for testing
115115
# @return [Boolean] If the string has valid CPU type characters
116-
def self.is_valid_cpu?(str)
116+
def self.is_valid_cpu?(str) # rubocop:disable Naming/PredicatePrefix
117117
return false unless is_non_empty_string?(str)
118118
return false if has_non_printable_char?(str)
119119
return false if str.length > 200
@@ -124,7 +124,7 @@ def self.is_valid_cpu?(str)
124124
# Verify the memory string is valid
125125
# @param [String] str String for testing
126126
# @return [Boolean] If the string has valid memory type characters
127-
def self.is_valid_memory?(str)
127+
def self.is_valid_memory?(str) # rubocop:disable Naming/PredicatePrefix
128128
return false unless is_non_empty_string?(str)
129129
return false if has_non_printable_char?(str)
130130
return false if str.length > 200
@@ -135,7 +135,7 @@ def self.is_valid_memory?(str)
135135
# Verify the GPU type string is valid
136136
# @param [String] str String for testing
137137
# @return [Boolean] If the string has valid GPU type characters
138-
def self.is_valid_gpu?(str)
138+
def self.is_valid_gpu?(str) # rubocop:disable Naming/PredicatePrefix
139139
return false unless is_non_empty_string?(str)
140140
return false if has_non_printable_char?(str)
141141
return false if str.length > 200
@@ -148,11 +148,11 @@ def self.is_valid_gpu?(str)
148148
# @return [Boolean] If the string has valid browser plugin characters
149149
# @note This string can be empty if there are no browser plugins
150150
# @todo Verify if the ruby version statement is still necessary
151-
def self.is_valid_browser_plugins?(str)
151+
def self.is_valid_browser_plugins?(str) # rubocop:disable Naming/PredicatePrefix
152152
return false unless is_non_empty_string?(str)
153153
return false if str.length > 1000
154154

155-
if str.encoding === Encoding.find('UTF-8')
155+
if str.encoding == Encoding.find('UTF-8') # Style/CaseEquality: Avoid the use of the case equality operator `===`.
156156
(str =~ /[^\w\d\s()-.,';_!\302\256]/u).nil?
157157
else
158158
(str =~ /[^\w\d\s()-.,';_!\302\256]/n).nil?

modules/social_engineering/text_to_voice/module.rb

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@
44
# See the file 'doc/COPYING' for copying permission
55
#
66
class Text_to_voice < BeEF::Core::Command
7-
require 'espeak'
8-
include ESpeak
9-
107
def pre_send
11-
# Ensure lame and espeak are installed
8+
# Check for required binaries
9+
if IO.popen(%w[which espeak], 'r').read.to_s.eql?('')
10+
print_error('[Text to Voice] eSpeak is not in $PATH (brew install espeak on macOS, apt-get install espeak on Linux)')
11+
return
12+
end
1213
if IO.popen(%w[which lame], 'r').read.to_s.eql?('')
13-
print_error('[Text to Voice] Lame is not in $PATH (apt-get install lame)')
14+
print_error('[Text to Voice] Lame is not in $PATH (brew install lame on macOS, apt-get install lame on Linux)')
1415
return
1516
end
16-
if IO.popen(%w[which espeak], 'r').read.to_s.eql?('')
17-
print_error('[Text to Voice] eSpeak is not in $PATH (apt-get install espeak)')
17+
18+
# Load espeak gem (only if binaries are available)
19+
begin
20+
require 'espeak'
21+
include ESpeak
22+
rescue LoadError, StandardError => e
23+
print_error("[Text to Voice] Failed to load espeak gem: #{e.message}")
1824
return
1925
end
2026

@@ -25,9 +31,16 @@ def pre_send
2531
message = input['value'] if input['name'] == 'message'
2632
language = input['value'] if input['name'] == 'language'
2733
end
28-
unless Voice.all.map(&:language).include?(language)
29-
print_error("[Text to Voice] Language '#{language}' is not supported")
30-
print_more("Supported languages: #{Voice.all.map(&:language).join(',')}")
34+
35+
# Validate language
36+
begin
37+
unless Voice.all.map(&:language).include?(language)
38+
print_error("[Text to Voice] Language '#{language}' is not supported")
39+
print_more("Supported languages: #{Voice.all.map(&:language).join(',')}")
40+
return
41+
end
42+
rescue StandardError => e
43+
print_error("[Text to Voice] Could not validate language: #{e.message}")
3144
return
3245
end
3346

spec/beef/core/extension_spec.rb

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#
2+
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
3+
# Browser Exploitation Framework (BeEF) - https://beefproject.com
4+
# See the file 'doc/COPYING' for copying permission
5+
#
6+
7+
RSpec.describe BeEF::Extension do
8+
let(:config) { BeEF::Core::Configuration.instance }
9+
10+
describe '.is_present' do
11+
it 'returns true when extension exists in configuration' do
12+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
13+
expect(described_class.is_present('test_ext')).to be true
14+
end
15+
16+
it 'returns false when extension does not exist' do
17+
allow(config).to receive(:get).with('beef.extension').and_return({})
18+
expect(described_class.is_present('nonexistent')).to be false
19+
end
20+
21+
it 'converts extension key to string' do
22+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
23+
expect(described_class.is_present(:test_ext)).to be true
24+
end
25+
end
26+
27+
describe '.is_enabled' do
28+
it 'returns true when extension is present and enabled' do
29+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
30+
allow(config).to receive(:get).with('beef.extension.test_ext.enable').and_return(true)
31+
expect(described_class.is_enabled('test_ext')).to be true
32+
end
33+
34+
it 'returns false when extension is not present' do
35+
allow(config).to receive(:get).with('beef.extension').and_return({})
36+
expect(described_class.is_enabled('nonexistent')).to be false
37+
end
38+
39+
it 'returns false when extension is disabled' do
40+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
41+
allow(config).to receive(:get).with('beef.extension.test_ext.enable').and_return(false)
42+
expect(described_class.is_enabled('test_ext')).to be false
43+
end
44+
end
45+
46+
describe '.is_loaded' do
47+
it 'returns true when extension is enabled and loaded' do
48+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
49+
allow(config).to receive(:get).with('beef.extension.test_ext.enable').and_return(true)
50+
allow(config).to receive(:get).with('beef.extension.test_ext.loaded').and_return(true)
51+
expect(described_class.is_loaded('test_ext')).to be true
52+
end
53+
54+
it 'returns false when extension is not enabled' do
55+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
56+
allow(config).to receive(:get).with('beef.extension.test_ext.enable').and_return(false)
57+
expect(described_class.is_loaded('test_ext')).to be false
58+
end
59+
60+
it 'returns false when extension is not loaded' do
61+
allow(config).to receive(:get).with('beef.extension').and_return({ 'test_ext' => {} })
62+
allow(config).to receive(:get).with('beef.extension.test_ext.enable').and_return(true)
63+
allow(config).to receive(:get).with('beef.extension.test_ext.loaded').and_return(false)
64+
expect(described_class.is_loaded('test_ext')).to be false
65+
end
66+
end
67+
68+
describe '.load' do
69+
it 'returns true when extension file exists' do
70+
ext_path = "#{$root_dir}/extensions/test_ext/extension.rb"
71+
allow(File).to receive(:exist?).with(ext_path).and_return(true)
72+
allow(config).to receive(:set).with('beef.extension.test_ext.loaded', true).and_return(true)
73+
# Stub require on the module itself since it's called directly
74+
allow(described_class).to receive(:require).with(ext_path)
75+
expect(described_class.load('test_ext')).to be true
76+
end
77+
78+
it 'returns false when extension file does not exist' do
79+
ext_path = "#{$root_dir}/extensions/test_ext/extension.rb"
80+
allow(File).to receive(:exist?).with(ext_path).and_return(false)
81+
expect(described_class.load('test_ext')).to be false
82+
end
83+
84+
it 'sets loaded flag to true when successfully loaded' do
85+
ext_path = "#{$root_dir}/extensions/test_ext/extension.rb"
86+
allow(File).to receive(:exist?).with(ext_path).and_return(true)
87+
allow(described_class).to receive(:require).with(ext_path)
88+
expect(config).to receive(:set).with('beef.extension.test_ext.loaded', true).and_return(true)
89+
described_class.load('test_ext')
90+
end
91+
92+
it 'handles errors during loading gracefully' do
93+
ext_path = "#{$root_dir}/extensions/test_ext/extension.rb"
94+
allow(File).to receive(:exist?).with(ext_path).and_return(true)
95+
allow(described_class).to receive(:require).with(ext_path).and_raise(StandardError.new('Load error'))
96+
# The rescue block calls print_more which may return a value, so just verify it doesn't raise
97+
expect { described_class.load('test_ext') }.not_to raise_error
98+
end
99+
end
100+
end

spec/beef/core/extensions_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
#
2+
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
3+
# Browser Exploitation Framework (BeEF) - https://beefproject.com
4+
# See the file 'doc/COPYING' for copying permission
5+
#
6+
17
RSpec.describe 'BeEF Extensions' do
28

39
it 'loaded successfully' do

0 commit comments

Comments
 (0)