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 SwiftPackageManagerAnalyzer extends AbstractFileTypeAnalyzer {
45
46
47
48
49 private static final String ANALYZER_NAME = "SWIFT Package Manager Analyzer";
50
51
52
53
54 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
55
56
57
58
59 public static final String SPM_FILE_NAME = "Package.swift";
60
61
62
63
64 private static final FileFilter SPM_FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(SPM_FILE_NAME).build();
65
66
67
68
69
70 private static final Pattern SPM_BLOCK_PATTERN = Pattern.compile("let[^=]+=\\s*Package\\s*\\(\\s*([^)]*)\\s*\\)", Pattern.DOTALL);
71
72
73
74
75
76
77 @Override
78 protected FileFilter getFileFilter() {
79 return SPM_FILE_FILTER;
80 }
81
82 @Override
83 protected void initializeFileTypeAnalyzer() {
84
85 }
86
87
88
89
90
91
92 @Override
93 public String getName() {
94 return ANALYZER_NAME;
95 }
96
97
98
99
100
101
102 @Override
103 public AnalysisPhase getAnalysisPhase() {
104 return ANALYSIS_PHASE;
105 }
106
107
108
109
110
111
112
113 @Override
114 protected String getAnalyzerEnabledSettingKey() {
115 return Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED;
116 }
117
118 @Override
119 protected void analyzeDependency(Dependency dependency, Engine engine)
120 throws AnalysisException {
121
122 String contents;
123 try {
124 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
125 } catch (IOException e) {
126 throw new AnalysisException(
127 "Problem occurred while reading dependency file.", e);
128 }
129 final Matcher matcher = SPM_BLOCK_PATTERN.matcher(contents);
130 if (matcher.find()) {
131 final String packageDescription = matcher.group(1);
132 if (packageDescription.isEmpty()) {
133 return;
134 }
135
136 final EvidenceCollection product = dependency.getProductEvidence();
137 final EvidenceCollection vendor = dependency.getVendorEvidence();
138
139
140
141 final String name = addStringEvidence(product, packageDescription, "name", "name", Confidence.HIGHEST);
142 if (name != null && !name.isEmpty()) {
143 vendor.addEvidence(SPM_FILE_NAME, "name_project", name, Confidence.HIGHEST);
144 }
145 }
146 setPackagePath(dependency);
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160 private String addStringEvidence(EvidenceCollection evidences,
161 String packageDescription, String field, String fieldPattern, Confidence confidence) {
162 String value = "";
163
164 final Matcher matcher = Pattern.compile(
165 String.format("%s *:\\s*\"([^\"]*)", fieldPattern), Pattern.DOTALL).matcher(packageDescription);
166 if (matcher.find()) {
167 value = matcher.group(1);
168 }
169
170 if (value != null) {
171 value = value.trim();
172 if (value.length() > 0) {
173 evidences.addEvidence(SPM_FILE_NAME, field, value, confidence);
174 }
175 }
176
177 return value;
178 }
179
180
181
182
183
184
185 private void setPackagePath(Dependency dep) {
186 final File file = new File(dep.getFilePath());
187 final String parent = file.getParent();
188 if (parent != null) {
189 dep.setPackagePath(parent);
190 }
191 }
192 }