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 java.io.File;
21 import java.io.FileFilter;
22 import java.io.IOException;
23 import java.nio.charset.Charset;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 import org.apache.commons.io.FileUtils;
28 import org.owasp.dependencycheck.Engine;
29 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
30 import org.owasp.dependencycheck.dependency.Confidence;
31 import org.owasp.dependencycheck.dependency.Dependency;
32 import org.owasp.dependencycheck.dependency.EvidenceCollection;
33 import org.owasp.dependencycheck.utils.FileFilterBuilder;
34 import org.owasp.dependencycheck.utils.Settings;
35
36
37
38
39
40
41
42
43 @Experimental
44 public class CocoaPodsAnalyzer extends AbstractFileTypeAnalyzer {
45
46
47
48
49
50
51
52
53 private static final String ANALYZER_NAME = "CocoaPods Package Analyzer";
54
55
56
57
58 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
59
60
61
62
63 public static final String PODSPEC = "podspec";
64
65
66
67 private static final FileFilter PODSPEC_FILTER = FileFilterBuilder.newInstance().addExtensions(PODSPEC).build();
68
69
70
71
72
73 private static final Pattern PODSPEC_BLOCK_PATTERN = Pattern.compile("Pod::Spec\\.new\\s+?do\\s+?\\|(.+?)\\|");
74
75
76
77
78
79
80 @Override
81 protected FileFilter getFileFilter() {
82 return PODSPEC_FILTER;
83 }
84
85 @Override
86 protected void initializeFileTypeAnalyzer() {
87
88 }
89
90
91
92
93
94
95 @Override
96 public String getName() {
97 return ANALYZER_NAME;
98 }
99
100
101
102
103
104
105 @Override
106 public AnalysisPhase getAnalysisPhase() {
107 return ANALYSIS_PHASE;
108 }
109
110
111
112
113
114
115
116 @Override
117 protected String getAnalyzerEnabledSettingKey() {
118 return Settings.KEYS.ANALYZER_COCOAPODS_ENABLED;
119 }
120
121 @Override
122 protected void analyzeDependency(Dependency dependency, Engine engine)
123 throws AnalysisException {
124
125 String contents;
126 try {
127 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
128 } catch (IOException e) {
129 throw new AnalysisException(
130 "Problem occurred while reading dependency file.", e);
131 }
132 final Matcher matcher = PODSPEC_BLOCK_PATTERN.matcher(contents);
133 if (matcher.find()) {
134 contents = contents.substring(matcher.end());
135 final String blockVariable = matcher.group(1);
136
137 final EvidenceCollection vendor = dependency.getVendorEvidence();
138 final EvidenceCollection product = dependency.getProductEvidence();
139 final EvidenceCollection version = dependency.getVersionEvidence();
140
141 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
142 if (!name.isEmpty()) {
143 vendor.addEvidence(PODSPEC, "name_project", name, Confidence.HIGHEST);
144 }
145 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.HIGHEST);
146
147 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
148 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
149 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
150
151 addStringEvidence(version, contents, blockVariable, "version", "version", Confidence.HIGHEST);
152 }
153
154 setPackagePath(dependency);
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169 private String addStringEvidence(EvidenceCollection evidences, String contents,
170 String blockVariable, String field, String fieldPattern, Confidence confidence) {
171 String value = "";
172
173
174 final Matcher arrayMatcher = Pattern.compile(
175 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\{\\s*?(.*?)\\s*?\\}", blockVariable, fieldPattern),
176 Pattern.CASE_INSENSITIVE).matcher(contents);
177 if (arrayMatcher.find()) {
178 value = arrayMatcher.group(1);
179 } else {
180 final Matcher matcher = Pattern.compile(
181 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern),
182 Pattern.CASE_INSENSITIVE).matcher(contents);
183 if (matcher.find()) {
184 value = matcher.group(2);
185 }
186 }
187 if (value.length() > 0) {
188 evidences.addEvidence(PODSPEC, field, value, confidence);
189 }
190 return value;
191 }
192
193
194
195
196
197
198 private void setPackagePath(Dependency dep) {
199 final File file = new File(dep.getFilePath());
200 final String parent = file.getParent();
201 if (parent != null) {
202 dep.setPackagePath(parent);
203 }
204 }
205 }