pluginscan 0.9.0
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 +7 -0
- data/.gitignore +13 -0
- data/.gitlab-ci.yml +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +46 -0
- data/.rubocop_todo.yml +36 -0
- data/CHANGELOG.md +89 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +90 -0
- data/README.md +56 -0
- data/Rakefile +2 -0
- data/TODO.md +8 -0
- data/bin/pluginscan +53 -0
- data/lib/file_creator.rb +18 -0
- data/lib/pluginscan.rb +69 -0
- data/lib/pluginscan/error.rb +9 -0
- data/lib/pluginscan/error_printer.rb +17 -0
- data/lib/pluginscan/file_finder.rb +42 -0
- data/lib/pluginscan/printer.rb +14 -0
- data/lib/pluginscan/reports/cloc_report.rb +27 -0
- data/lib/pluginscan/reports/cloc_report/cloc.rb +21 -0
- data/lib/pluginscan/reports/cloc_report/cloc_printer.rb +42 -0
- data/lib/pluginscan/reports/cloc_report/cloc_scanner.rb +41 -0
- data/lib/pluginscan/reports/cloc_report/system_cloc.rb +33 -0
- data/lib/pluginscan/reports/issues_report.rb +24 -0
- data/lib/pluginscan/reports/issues_report/error_list_printer.rb +99 -0
- data/lib/pluginscan/reports/issues_report/issue_checks.rb +382 -0
- data/lib/pluginscan/reports/issues_report/issue_checks/check.rb +55 -0
- data/lib/pluginscan/reports/issues_report/issue_checks/comment_checker.rb +13 -0
- data/lib/pluginscan/reports/issues_report/issue_checks/function_check.rb +32 -0
- data/lib/pluginscan/reports/issues_report/issue_checks/variable_check.rb +14 -0
- data/lib/pluginscan/reports/issues_report/issue_checks/variable_safety_checker.rb +112 -0
- data/lib/pluginscan/reports/issues_report/issues_models/check_findings.rb +29 -0
- data/lib/pluginscan/reports/issues_report/issues_models/issues.rb +31 -0
- data/lib/pluginscan/reports/issues_report/issues_printer.rb +34 -0
- data/lib/pluginscan/reports/issues_report/issues_printer/check_findings_printer.rb +37 -0
- data/lib/pluginscan/reports/issues_report/issues_printer/file_issues_printer.rb +36 -0
- data/lib/pluginscan/reports/issues_report/issues_printer/finding_printer.rb +38 -0
- data/lib/pluginscan/reports/issues_report/issues_printer_factory.rb +19 -0
- data/lib/pluginscan/reports/issues_report/issues_scanner.rb +49 -0
- data/lib/pluginscan/reports/issues_report/issues_scanner/file_issues_scanner.rb +39 -0
- data/lib/pluginscan/reports/issues_report/issues_scanner/line_issues_scanner.rb +15 -0
- data/lib/pluginscan/reports/issues_report/issues_scanner/utf8_checker.rb +14 -0
- data/lib/pluginscan/reports/sloccount_report.rb +26 -0
- data/lib/pluginscan/reports/sloccount_report/sloccount.rb +19 -0
- data/lib/pluginscan/reports/sloccount_report/sloccount_printer.rb +22 -0
- data/lib/pluginscan/reports/sloccount_report/sloccount_scanner.rb +86 -0
- data/lib/pluginscan/reports/vulnerability_report.rb +28 -0
- data/lib/pluginscan/reports/vulnerability_report/advisories_api.rb +23 -0
- data/lib/pluginscan/reports/vulnerability_report/vulnerabilities_printer.rb +55 -0
- data/lib/pluginscan/reports/vulnerability_report/vulnerability_scanner.rb +17 -0
- data/lib/pluginscan/reports/vulnerability_report/wp_vuln_db_api.rb +77 -0
- data/lib/pluginscan/version.rb +3 -0
- data/pluginscan.gemspec +31 -0
- data/spec/acceptance/cloc_spec.rb +54 -0
- data/spec/acceptance/create_error_list_file_spec.rb +29 -0
- data/spec/acceptance/issues_spec.rb +197 -0
- data/spec/acceptance/pluginscan_spec.rb +18 -0
- data/spec/acceptance/sloccount_spec.rb +39 -0
- data/spec/acceptance/vulnerabilities_spec.rb +57 -0
- data/spec/acceptance_spec_helper.rb +10 -0
- data/spec/checks_examples_spec.rb +352 -0
- data/spec/file_creator_spec.rb +51 -0
- data/spec/pluginscan/cloc_scanner/cloc_scanner_spec.rb +64 -0
- data/spec/pluginscan/cloc_scanner/cloc_spec.rb +30 -0
- data/spec/pluginscan/file_finder_spec.rb +91 -0
- data/spec/pluginscan/issues_scanner/check_findings_spec.rb +22 -0
- data/spec/pluginscan/issues_scanner/error_list_printer_ignores_spec.rb +35 -0
- data/spec/pluginscan/issues_scanner/error_list_printer_spec.rb +42 -0
- data/spec/pluginscan/issues_scanner/file_issues_scanner_spec.rb +25 -0
- data/spec/pluginscan/issues_scanner/issues_printer_factory_spec.rb +9 -0
- data/spec/pluginscan/issues_scanner/issues_spec.rb +55 -0
- data/spec/pluginscan/issues_scanner/variable_check_spec.rb +13 -0
- data/spec/pluginscan/issues_scanner/variable_safety_checker_spec.rb +81 -0
- data/spec/pluginscan/issues_scanner_spec.rb +21 -0
- data/spec/pluginscan/sloccount_scanner/sloccount_scanner_spec.rb +95 -0
- data/spec/pluginscan/sloccount_scanner/sloccount_spec.rb +72 -0
- data/spec/pluginscan/vulnerability_scanner_spec.rb +96 -0
- data/spec/process_spec_helper.rb +6 -0
- data/spec/spec_helper.rb +70 -0
- data/spec/support/acceptance_helpers.rb +68 -0
- data/spec/support/file_helpers.rb +35 -0
- data/spec/support/heredoc_helper.rb +7 -0
- data/spec/support/process_helpers.rb +25 -0
- data/spec/support/shared_examples_for_issue_checks.rb +31 -0
- data/spec/support/vcr_helper.rb +6 -0
- data/vcr_cassettes/wpvulndb/relevanssi.yml +78 -0
- metadata +342 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'file_creator'
|
|
3
|
+
|
|
4
|
+
RSpec.describe FileCreator do
|
|
5
|
+
describe '#create' do
|
|
6
|
+
subject(:create) { FileCreator.new.create(file_name) }
|
|
7
|
+
let(:file_name) { "pluginscan.scan" }
|
|
8
|
+
|
|
9
|
+
it 'tries to create a file with the given name' do
|
|
10
|
+
allow(File).to receive(:new)
|
|
11
|
+
create
|
|
12
|
+
expect(File).to have_received(:new).with(file_name, 'w')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'returns the file if it successfully created it' do
|
|
16
|
+
file = double(File)
|
|
17
|
+
allow(File).to receive(:new).and_return file
|
|
18
|
+
expect(create).to eq file
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'if the filename is not a writeable location' do
|
|
22
|
+
before { allow(File).to receive(:new).and_raise(Errno::EACCES) }
|
|
23
|
+
it 'raises an error' do
|
|
24
|
+
expect{ create }.to raise_error(FileCreator::Error, "You do not have permission to write to that location (#{file_name})")
|
|
25
|
+
end
|
|
26
|
+
# Real example:
|
|
27
|
+
# File.new('/etc/foo', 'w')
|
|
28
|
+
# => Errno::EACCES: Permission denied @ rb_sysopen - /etc/foo
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'if the filename is a directory name' do
|
|
32
|
+
before { allow(File).to receive(:new).and_raise(Errno::EISDIR) }
|
|
33
|
+
it 'raises an error' do
|
|
34
|
+
expect{ create }.to raise_error(FileCreator::Error, "File name is a directory (#{file_name})")
|
|
35
|
+
end
|
|
36
|
+
# Real example:
|
|
37
|
+
# File.new("/", 'w')
|
|
38
|
+
# => Errno::EISDIR: Is a directory @ rb_sysopen - /
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'if the filename is in a directory which does not exist' do
|
|
42
|
+
before { allow(File).to receive(:new).and_raise(Errno::ENOTDIR) }
|
|
43
|
+
it 'raises an error' do
|
|
44
|
+
expect{ create }.to raise_error(FileCreator::Error, "File name refers to a directory which does not exist (#{file_name})")
|
|
45
|
+
end
|
|
46
|
+
# Real example:
|
|
47
|
+
# File.new("foo/bar", 'w')
|
|
48
|
+
# => Errno::ENOTDIR: Not a directory @ rb_sysopen - foo/bar
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'process_spec_helper'
|
|
2
|
+
require 'support/heredoc_helper'
|
|
3
|
+
|
|
4
|
+
RSpec.describe CLOCScanner, type: :process do
|
|
5
|
+
describe "#scan" do
|
|
6
|
+
it "returns a CLOC object when cloc is successful" do
|
|
7
|
+
stub_dir_exists
|
|
8
|
+
cloc_output = <<-EOS.heredoc_unindent
|
|
9
|
+
files,language,blank,comment,code,"github.com/AlDanial/cloc v 1.70 T=0.29 s (290.6 files/s, 66866.8 lines/s)"
|
|
10
|
+
20,PHP,4571,0,6641
|
|
11
|
+
2,JSON,0,0,1770
|
|
12
|
+
1,JavaScript,260,184,1263
|
|
13
|
+
EOS
|
|
14
|
+
system_cloc = fake_system_cloc(result: cloc_output, process_status: successful_process_status)
|
|
15
|
+
expect(CLOCScanner.new(system_cloc).scan("my_directory")).to be_a(CLOC)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# EXCEPTION HANDLING:
|
|
19
|
+
#####################
|
|
20
|
+
|
|
21
|
+
it "raises an error when no directory is passed" do
|
|
22
|
+
expect{ CLOCScanner.new(fake_system_cloc).scan(nil) }.to raise_error CLOCScanner::ArgumentError
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "raises an error when the directory doesn't exist" do
|
|
26
|
+
allow(Dir).to receive(:exist?).and_return false
|
|
27
|
+
expect{ CLOCScanner.new(fake_system_cloc).scan("my_directory") }.to raise_error CLOCScanner::NoDirectory
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "raises an error when cloc was not available" do
|
|
31
|
+
stub_dir_exists
|
|
32
|
+
system_cloc = fake_system_cloc(which_result: which_failure)
|
|
33
|
+
expect{ CLOCScanner.new(system_cloc).scan("my_directory") }.to raise_error CLOCScanner::Unavailable
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'raises an error when cloc returns an unrecognised error' do
|
|
37
|
+
stub_dir_exists
|
|
38
|
+
system_cloc = fake_system_cloc(result: "Some nonsense", process_status: failed_process_status)
|
|
39
|
+
expect{ CLOCScanner.new(system_cloc).scan("my_directory") }.to raise_error CLOCScanner::Exception
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'raises an error when the output could not be parsed' do
|
|
43
|
+
stub_dir_exists
|
|
44
|
+
cloc_output = <<-EOS.heredoc_unindent
|
|
45
|
+
files,language,blank,comment,code,"github.com/AlDanial/cloc v 1.70 T=0.29 s (290.6 files/s, 66866.8 lines/s)"
|
|
46
|
+
20",PHP,4571,0,6641
|
|
47
|
+
EOS
|
|
48
|
+
system_cloc = fake_system_cloc(result: cloc_output)
|
|
49
|
+
expect{ CLOCScanner.new(system_cloc).scan("my_directory") }.to raise_error CLOCScanner::CSVError
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def fake_system_cloc(result: "foo", process_status: successful_process_status, which_result: which_success('cloc'))
|
|
53
|
+
instance_double(
|
|
54
|
+
SystemCloc,
|
|
55
|
+
call: [result, process_status],
|
|
56
|
+
which: which_result
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def stub_dir_exists
|
|
61
|
+
allow(Dir).to receive(:exist?).and_return true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe CLOC do
|
|
4
|
+
describe ".language_counts" do
|
|
5
|
+
it "returns an empty array when there is no code" do
|
|
6
|
+
csv = CSV.parse("", headers: true)
|
|
7
|
+
expect(CLOC.new(csv).language_counts).to eq []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "returns an array of language count objects" do
|
|
11
|
+
csv = CSV.parse(CLOC_CSV_OUTPUT.lstrip, headers: true)
|
|
12
|
+
cloc = CLOC.new(csv)
|
|
13
|
+
expect(cloc.language_counts[2].language).to eq "Ruby"
|
|
14
|
+
expect(cloc.language_counts[2].sloc).to eq 1119
|
|
15
|
+
expect(cloc.language_counts[2].file_count).to eq 30
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Output starts with a newline
|
|
20
|
+
CLOC_CSV_OUTPUT = <<-EOS
|
|
21
|
+
|
|
22
|
+
files,language,blank,comment,code,"http://cloc.sourceforge.net v 1.62 T=0.34 s (106.4 files/s, 28129.6 lines/s)"
|
|
23
|
+
1,HTML,2070,0,2734
|
|
24
|
+
1,Javascript,220,173,1166
|
|
25
|
+
30,Ruby,303,154,1119
|
|
26
|
+
2,JSON,0,0,758
|
|
27
|
+
1,CSS,80,70,649
|
|
28
|
+
1,YAML,7,0,17
|
|
29
|
+
EOS
|
|
30
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::FileFinder, type: :file do
|
|
4
|
+
describe ".count" do
|
|
5
|
+
it "returns 0 when there are no files" do
|
|
6
|
+
setup_tempdir('tmp')
|
|
7
|
+
|
|
8
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
9
|
+
expect(finder.count).to eq 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "returns 0 when there are only directories" do
|
|
13
|
+
setup_tempdir('tmp')
|
|
14
|
+
add_directory('tmp', 'foo')
|
|
15
|
+
|
|
16
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
17
|
+
expect(finder.count).to eq 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "returns 3 when there are 3 files" do
|
|
21
|
+
setup_tempdir('tmp')
|
|
22
|
+
add_php_file('tmp')
|
|
23
|
+
|
|
24
|
+
add_directory('tmp', 'foo')
|
|
25
|
+
add_non_php_file('tmp/foo')
|
|
26
|
+
|
|
27
|
+
add_directory('tmp', 'foo/bar')
|
|
28
|
+
add_php_file('tmp/foo/bar')
|
|
29
|
+
|
|
30
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
31
|
+
expect(finder.count).to eq 3
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "caches the value" do
|
|
35
|
+
setup_tempdir('tmp')
|
|
36
|
+
add_php_file('tmp')
|
|
37
|
+
|
|
38
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
39
|
+
finder.count
|
|
40
|
+
|
|
41
|
+
setup_tempdir('tmp')
|
|
42
|
+
|
|
43
|
+
# We removed the file, but the result should stay the same:
|
|
44
|
+
expect(finder.count).to eq 1
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe ".php_files" do
|
|
49
|
+
it "returns [] when there are no files" do
|
|
50
|
+
setup_tempdir('tmp')
|
|
51
|
+
|
|
52
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
53
|
+
expect(finder.php_files).to eq []
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "returns [] when there are only directories" do
|
|
57
|
+
setup_tempdir('tmp')
|
|
58
|
+
add_directory('tmp', 'foo')
|
|
59
|
+
|
|
60
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
61
|
+
expect(finder.php_files).to eq []
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "returns two filenames when there are 2 php files" do
|
|
65
|
+
setup_tempdir('tmp')
|
|
66
|
+
php_file_name1 = add_php_file('tmp')
|
|
67
|
+
|
|
68
|
+
add_directory('tmp', 'foo')
|
|
69
|
+
add_non_php_file('tmp/foo')
|
|
70
|
+
|
|
71
|
+
add_directory('tmp', 'foo/bar')
|
|
72
|
+
php_file_name2 = add_php_file('tmp/foo/bar')
|
|
73
|
+
|
|
74
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
75
|
+
expect(finder.php_files).to eq [php_file_name1, php_file_name2]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "caches the result" do
|
|
79
|
+
setup_tempdir('tmp')
|
|
80
|
+
php_file_name = add_php_file('tmp')
|
|
81
|
+
|
|
82
|
+
finder = Pluginscan::FileFinder.new('tmp')
|
|
83
|
+
finder.php_files
|
|
84
|
+
|
|
85
|
+
setup_tempdir('tmp')
|
|
86
|
+
|
|
87
|
+
# We removed the file, but the result should stay the same:
|
|
88
|
+
expect(finder.php_files).to eq [php_file_name]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::CheckFindings do
|
|
4
|
+
describe "count" do
|
|
5
|
+
subject(:check_findings) { Pluginscan::CheckFindings.new(check) }
|
|
6
|
+
let(:check) { double('Check') }
|
|
7
|
+
|
|
8
|
+
it "returns 0 when no issues were found" do
|
|
9
|
+
expect(check_findings.count).to eq 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "returns 3 when 3 issues were found" do
|
|
13
|
+
finding = double('Finding')
|
|
14
|
+
3.times do
|
|
15
|
+
check_findings.add [finding]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
expect(check_findings.count).to eq 3
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::ErrorListPrinter do
|
|
4
|
+
describe "error_lines", "showing ignores" do
|
|
5
|
+
it 'marks lines as ignored where we think they are safe' do
|
|
6
|
+
check_double = Struct.new(:name)
|
|
7
|
+
check = check_double.new("Bad thing")
|
|
8
|
+
check_findings = Pluginscan::CheckFindings.new(check)
|
|
9
|
+
check_findings.add [Pluginscan::Finding.new(17, " foo bar baz", "bar", true)]
|
|
10
|
+
|
|
11
|
+
issues = Pluginscan::Issues.new(
|
|
12
|
+
"./foo/bar.php" => [check_findings],
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
expect(Pluginscan::ErrorListPrinter.new.error_lines(issues)).to eq [
|
|
16
|
+
%("./foo/bar.php", line 17, col 7: [Bad thing][IGNORE] foo bar baz),
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "error_lines", "hiding ignores" do
|
|
22
|
+
it 'hide lines where we think they are safe' do
|
|
23
|
+
check_double = Struct.new(:name)
|
|
24
|
+
check = check_double.new("Bad thing")
|
|
25
|
+
check_findings = Pluginscan::CheckFindings.new(check)
|
|
26
|
+
check_findings.add [Pluginscan::Finding.new(17, " foo bar baz", "bar", true)]
|
|
27
|
+
|
|
28
|
+
issues = Pluginscan::Issues.new(
|
|
29
|
+
"./foo/bar.php" => [check_findings],
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
expect(Pluginscan::ErrorListPrinter.new(true).error_lines(issues)).to be_empty
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::ErrorListPrinter do
|
|
4
|
+
describe "error_lines" do
|
|
5
|
+
it 'returns nothing when there are no issues' do
|
|
6
|
+
issues = Pluginscan::Issues.new({})
|
|
7
|
+
expect(Pluginscan::ErrorListPrinter.new.error_lines(issues)).to eq []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'returns an array of vim-compatible error lines when there were two issues in two different files' do
|
|
11
|
+
check1 = double(name: "Bad thing")
|
|
12
|
+
check_findings1 = Pluginscan::CheckFindings.new(check1)
|
|
13
|
+
check_findings1.add [Pluginscan::Finding.new(17, " foo bar baz", "bar")]
|
|
14
|
+
|
|
15
|
+
check2 = double(name: "Other bad thing")
|
|
16
|
+
check_findings2 = Pluginscan::CheckFindings.new(check2)
|
|
17
|
+
check_findings2.add [Pluginscan::Finding.new(23, "\thaz qux qix", "qux")]
|
|
18
|
+
|
|
19
|
+
issues = Pluginscan::Issues.new(
|
|
20
|
+
"./foo/bar.php" => [check_findings1],
|
|
21
|
+
"./foo/bar/baz.php" => [],
|
|
22
|
+
"./foo/bar/qux.php" => [check_findings2],
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
expect(Pluginscan::ErrorListPrinter.new.error_lines(issues)).to eq [
|
|
26
|
+
%("./foo/bar.php", line 17, col 7: [Bad thing] foo bar baz),
|
|
27
|
+
%("./foo/bar/qux.php", line 23, col 6: [Other bad thing] haz qux qix), # looks like vim treats tabs as single spaces for the purposes of using columns
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'escapes colons (:) - these mess with the formatting' do
|
|
32
|
+
check = double(name: "Bad thing")
|
|
33
|
+
check_findings = Pluginscan::CheckFindings.new(check)
|
|
34
|
+
source_line = %($retrieved_stats = $wpdb->get_var("SELECT COUNT(*) FROM " . $wpdb->prefix . "mlw_results W HERE (time_taken_real BETWEEN '".$stat_date." 00:00:00' AND '".$stat_end_date." 23:59:59') AND deleted=0");)
|
|
35
|
+
check_findings.add [Pluginscan::Finding.new(23, source_line, '$wpdb')]
|
|
36
|
+
issues = Pluginscan::Issues.new(
|
|
37
|
+
"./foo/bar.php" => [check_findings],
|
|
38
|
+
)
|
|
39
|
+
expect(Pluginscan::ErrorListPrinter.new.error_lines(issues).first).to include %q(00\:00\:00)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'support/shared_examples_for_issue_checks'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::FileIssuesScanner do
|
|
4
|
+
before(:all) { @scanner = Pluginscan::FileIssuesScanner.new(Pluginscan::THE_CHECKS) }
|
|
5
|
+
let(:runner_run_results) { @scanner.scan(file_contents) }
|
|
6
|
+
|
|
7
|
+
describe 'run' do
|
|
8
|
+
context 'with an empty file' do
|
|
9
|
+
let(:file_contents) { "" }
|
|
10
|
+
it "finds no results" do
|
|
11
|
+
expect(runner_run_results).to eq []
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "matches at the beginning of the line" do
|
|
16
|
+
# Artificial examples, but older versions of the `function list` helper
|
|
17
|
+
# would have failed to match these
|
|
18
|
+
it_behaves_like "matches lines containing", "$_POST", %($_POST[$tagname] : '';)
|
|
19
|
+
it_behaves_like "matches lines containing", "$wpdb", %($wpdb->prepare( " AND meta_value = %d", $old_id );)
|
|
20
|
+
it_behaves_like "matches lines containing", "wp_remote_post", %(wp_remote_post( $url, $req_args );)
|
|
21
|
+
it_behaves_like "matches lines containing", "glob", %(glob( $directory_pattern );)
|
|
22
|
+
it_behaves_like "matches lines containing", "wp_unslash", %(wp_unslash( $answer );)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::IssuesPrinterFactory do
|
|
4
|
+
describe ".create_printer" do
|
|
5
|
+
it 'raises an error if it gets an unknown format' do
|
|
6
|
+
expect{ Pluginscan::IssuesPrinterFactory.create_printer(:foo) }.to raise_error(Pluginscan::UnknownIssuesFormat)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::Issues do
|
|
4
|
+
def no_files_scanned
|
|
5
|
+
Pluginscan::Issues.new({})
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def three_files_scanned_no_issues
|
|
9
|
+
files_findings = {
|
|
10
|
+
"a" => [],
|
|
11
|
+
"b" => [],
|
|
12
|
+
"c" => [],
|
|
13
|
+
}
|
|
14
|
+
Pluginscan::Issues.new(files_findings)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
describe "scanned_files_count" do
|
|
19
|
+
it "returns 0 when no files were scanned" do
|
|
20
|
+
report = no_files_scanned
|
|
21
|
+
expect(report.scanned_files_count).to eq 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "returns 3 when 3 files were scanned" do
|
|
25
|
+
report = three_files_scanned_no_issues
|
|
26
|
+
expect(report.scanned_files_count).to eq 3
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe "found_problems_count" do
|
|
31
|
+
it "returns 0 when no files were scanned" do
|
|
32
|
+
report = no_files_scanned
|
|
33
|
+
expect(report.found_problems_count).to eq 0
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "returns 0 when no issues were found" do
|
|
37
|
+
report = three_files_scanned_no_issues
|
|
38
|
+
expect(report.found_problems_count).to eq 0
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns 6 when 6 issues were found" do
|
|
42
|
+
check_findings1 = double(count: 1)
|
|
43
|
+
check_findings2 = double(count: 3)
|
|
44
|
+
check_findings3 = double(count: 0)
|
|
45
|
+
check_findings4 = double(count: 2)
|
|
46
|
+
files_findings = {
|
|
47
|
+
"a" => [check_findings1, check_findings2],
|
|
48
|
+
"b" => [check_findings3],
|
|
49
|
+
"c" => [check_findings4],
|
|
50
|
+
}
|
|
51
|
+
report = Pluginscan::Issues.new(files_findings)
|
|
52
|
+
expect(report.found_problems_count).to eq 6
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Pluginscan::VariableCheck do
|
|
4
|
+
describe "#ignore?" do
|
|
5
|
+
it "returns true when there is 1 match and it is known to be safe" do
|
|
6
|
+
expect(described_class.new({}).ignore?("$_GET", "if ( isset( $_GET['action'] ) ) {")).to eq true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# it "returns false when there are 2 matches and only 1 is known safe" do
|
|
10
|
+
# expect(described_class.match_count("$_POST", "$submitted = isset( $_POST[$tagname] ) ? $_POST[$tagname] : '';")).to eq 2
|
|
11
|
+
# end
|
|
12
|
+
end
|
|
13
|
+
end
|