1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.analyzer;
19
20 import org.apache.commons.io.FileUtils;
21 import org.owasp.dependencycheck.Engine;
22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
23 import org.owasp.dependencycheck.dependency.Confidence;
24 import org.owasp.dependencycheck.dependency.Dependency;
25 import org.owasp.dependencycheck.dependency.EvidenceCollection;
26 import org.owasp.dependencycheck.utils.FileFilterBuilder;
27 import org.owasp.dependencycheck.utils.Settings;
28
29 import java.io.FileFilter;
30 import java.io.IOException;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39
40 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
41
42
43
44
45 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
46
47
48
49
50 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
51
52 private static final String GEMSPEC = "gemspec";
53
54 private static final FileFilter FILTER
55 = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
56
57 private static final String EMAIL = "email";
58
59
60
61
62 @Override
63 protected FileFilter getFileFilter() {
64 return FILTER;
65 }
66
67 @Override
68 protected void initializeFileTypeAnalyzer() throws Exception {
69
70 }
71
72
73
74
75
76
77 @Override
78 public String getName() {
79 return ANALYZER_NAME;
80 }
81
82
83
84
85
86
87 @Override
88 public AnalysisPhase getAnalysisPhase() {
89 return ANALYSIS_PHASE;
90 }
91
92
93
94
95
96
97 @Override
98 protected String getAnalyzerEnabledSettingKey() {
99 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
100 }
101
102
103
104
105 private static final Pattern GEMSPEC_BLOCK_INIT
106 = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
107
108 @Override
109 protected void analyzeFileType(Dependency dependency, Engine engine)
110 throws AnalysisException {
111 String contents;
112 try {
113 contents = FileUtils.readFileToString(dependency.getActualFile());
114 } catch (IOException e) {
115 throw new AnalysisException(
116 "Problem occurred while reading dependency file.", e);
117 }
118 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
119 if (matcher.find()) {
120 contents = contents.substring(matcher.end());
121 final String blockVariable = matcher.group(1);
122 final EvidenceCollection vendor = dependency.getVendorEvidence();
123 addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST);
124 addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST);
125 final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
126 if (email.isEmpty()) {
127 addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
128 }
129 addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM);
130 final EvidenceCollection product = dependency.getProductEvidence();
131 final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST);
132 if (!name.isEmpty()) {
133 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
134 }
135 addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW);
136 addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST);
137 }
138 }
139
140 private void addListEvidence(EvidenceCollection evidences, String contents,
141 String blockVariable, String field, Confidence confidence) {
142 final Matcher matcher = Pattern.compile(
143 String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents);
144 if (matcher.find()) {
145 final String value = matcher.group(1).replaceAll("['\"]", " ").trim();
146 evidences.addEvidence(GEMSPEC, field, value, confidence);
147 }
148 }
149
150 private String addStringEvidence(EvidenceCollection evidences, String contents,
151 String blockVariable, String field, Confidence confidence) {
152 final Matcher matcher = Pattern.compile(
153 String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents);
154 String value = "";
155 if (matcher.find()) {
156 value = matcher.group(2);
157 evidences.addEvidence(GEMSPEC, field, value, confidence);
158 }
159 return value;
160 }
161 }