View Javadoc
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) 2013 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.utils;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.regex.Matcher;
23  import java.util.regex.Pattern;
24  
25  /**
26   * <p>
27   * A utility class to extract version numbers from file names (or other strings containing version numbers.</p>
28   *
29   * @author Jeremy Long
30   */
31  public final class DependencyVersionUtil {
32  
33      /**
34       * Regular expression to extract version numbers from file names.
35       */
36      private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
37      /**
38       * Regular expression to extract a single version number without periods. This is a last ditch effort just to check in case we
39       * are missing a version number using the previous regex.
40       */
41      private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
42  
43      /**
44       * Private constructor for utility class.
45       */
46      private DependencyVersionUtil() {
47      }
48  
49      /**
50       * <p>
51       * A utility class to extract version numbers from file names (or other strings containing version numbers.</p>
52       * <pre>
53       * Example:
54       * Give the file name: library-name-1.4.1r2-release.jar
55       * This function would return: 1.4.1.r2</pre>
56       *
57       * @param text the text being analyzed
58       * @return a DependencyVersion containing the version
59       */
60      public static DependencyVersion parseVersion(String text) {
61          if (text == null) {
62              return null;
63          }
64          //'-' is a special case used within the CVE entries, just include it as the version.
65          if ("-".equals(text)) {
66              final DependencyVersion dv = new DependencyVersion();
67              final List<String> list = new ArrayList<String>();
68              list.add(text);
69              dv.setVersionParts(list);
70              return dv;
71          }
72          String version = null;
73          Matcher matcher = RX_VERSION.matcher(text);
74          if (matcher.find()) {
75              version = matcher.group();
76          }
77          //throw away the results if there are two things that look like version numbers
78          if (matcher.find()) {
79              return null;
80          }
81          if (version == null) {
82              matcher = RX_SINGLE_VERSION.matcher(text);
83              if (matcher.find()) {
84                  version = matcher.group();
85              } else {
86                  return null;
87              }
88              //throw away the results if there are two things that look like version numbers
89              if (matcher.find()) {
90                  return null;
91              }
92          }
93          if (version != null && version.endsWith("-py2") && version.length() > 4) {
94              version = version.substring(0, version.length() - 4);
95          }
96          return new DependencyVersion(version);
97      }
98  }