1 /*
2 * This file is part of dependency-check-core.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17 */
18 package org.owasp.dependencycheck.analyzer;
19
20 import java.io.File;
21
22 import org.apache.commons.io.FilenameUtils;
23 import org.apache.commons.io.filefilter.NameFileFilter;
24 import org.owasp.dependencycheck.Engine;
25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
26 import org.owasp.dependencycheck.dependency.Confidence;
27 import org.owasp.dependencycheck.dependency.Dependency;
28 import org.owasp.dependencycheck.utils.DependencyVersion;
29 import org.owasp.dependencycheck.utils.DependencyVersionUtil;
30
31 /**
32 *
33 * Takes a dependency and analyzes the filename and determines the hashes.
34 *
35 * @author Jeremy Long
36 */
37 public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
38
39 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
40 /**
41 * The name of the analyzer.
42 */
43 private static final String ANALYZER_NAME = "File Name Analyzer";
44 /**
45 * The phase that this analyzer is intended to run in.
46 */
47 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
48
49 /**
50 * Returns the name of the analyzer.
51 *
52 * @return the name of the analyzer.
53 */
54 @Override
55 public String getName() {
56 return ANALYZER_NAME;
57 }
58
59 /**
60 * Returns the phase that the analyzer is intended to run in.
61 *
62 * @return the phase that the analyzer is intended to run in.
63 */
64 @Override
65 public AnalysisPhase getAnalysisPhase() {
66 return ANALYSIS_PHASE;
67 }
68 //</editor-fold>
69
70 /**
71 * Python init files
72 */
73 private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
74 "__init__.py",
75 "__init__.pyc",
76 "__init__.pyo",
77 });
78
79 /**
80 * Collects information about the file name.
81 *
82 * @param dependency the dependency to analyze.
83 * @param engine the engine that is scanning the dependencies
84 * @throws AnalysisException is thrown if there is an error reading the JAR
85 * file.
86 */
87 @Override
88 public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
89
90 //strip any path information that may get added by ArchiveAnalyzer, etc.
91 final File f = dependency.getActualFile();
92 final String fileName = FilenameUtils.removeExtension(f.getName());
93
94 //add version evidence
95 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
96 if (version != null) {
97 // If the version number is just a number like 2 or 23, reduce the confidence
98 // a shade. This should hopefully correct for cases like log4j.jar or
99 // struts2-core.jar
100 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
101 dependency.getVersionEvidence().addEvidence("file", "name",
102 version.toString(), Confidence.MEDIUM);
103 } else {
104 dependency.getVersionEvidence().addEvidence("file", "version",
105 version.toString(), Confidence.HIGHEST);
106 }
107 dependency.getVersionEvidence().addEvidence("file", "name",
108 fileName, Confidence.MEDIUM);
109 }
110
111 if (!IGNORED_FILES.accept(f)) {
112 dependency.getProductEvidence().addEvidence("file", "name",
113 fileName, Confidence.HIGH);
114 dependency.getVendorEvidence().addEvidence("file", "name",
115 fileName, Confidence.HIGH);
116 }
117 }
118 }