##### Coverage Report - org.owasp.dependencycheck.utils.FileUtils

Classes in this File | Line Coverage | Branch Coverage | Complexity
FileUtils |
52% | 40/76
62% | 20/32
| 5.285714285714286;5.286

1 |  |
     /*
2 |  |
      * This file is part of dependency-check-core.
3 |  |
      *
4 |  |
      * Dependency-check-core is free software: you can redistribute it and/or modify it
5 |  |
      * under the terms of the GNU General Public License as published by the Free
6 |  |
      * Software Foundation, either version 3 of the License, or (at your option) any
7 |  |
      * later version.
8 |  |
      *
9 |  |
      * Dependency-check-core is distributed in the hope that it will be useful, but
10 |  |
      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 |  |
      * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 |  |
      * details.
13 |  |
      *
14 |  |
      * You should have received a copy of the GNU General Public License along with
15 |  |
      * dependency-check-core. If not, see http://www.gnu.org/licenses/.
16 |  |
      *
17 |  |
      * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
18 |  |
      */
19 |  |
     package org.owasp.dependencycheck.utils;
20 |  |
21 |  |
     import java.io.BufferedInputStream;
22 |  |
     import java.io.BufferedOutputStream;
23 |  |
     import java.io.File;
24 |  |
     import java.io.FileInputStream;
25 |  |
     import java.io.FileNotFoundException;
26 |  |
     import java.io.FileOutputStream;
27 |  |
     import java.io.IOException;
28 |  |
     import java.io.UnsupportedEncodingException;
29 |  |
     import java.net.URLDecoder;
30 |  |
     import java.util.logging.Level;
31 |  |
     import java.util.logging.Logger;
32 |  |
     import java.util.zip.ZipEntry;
33 |  |
     import java.util.zip.ZipInputStream;
34 |  |
     import org.owasp.dependencycheck.Engine;
35 |  |
36 |  |
     /**
37 |  |
      * A collection of utilities for processing information about files.
38 |  |
      *
39 |  |
      * @author Jeremy Long (jeremy.long@owasp.org)
40 |  |
      */
41 |  |
     public final class FileUtils {
42 |  |
43 |  |
         /**
44 |  |
          * The buffer size to use when extracting files from the archive.
45 |  |
          */
46 |  |
         private static final int BUFFER_SIZE = 4096;
47 |  |
48 |  |
         /**
49 |  |
          * Private constructor for a utility class.
50 |  |
          */
51 | 0 |
         private FileUtils() {
52 | 0 |
         }
53 |  |
54 |  |
         /**
55 |  |
          * Returns the (lowercase) file extension for a specified file.
56 |  |
          *
57 |  |
          * @param fileName the file name to retrieve the file extension from.
58 |  |
          * @return the file extension.
59 |  |
          */
60 |  |
         public static String getFileExtension(String fileName) {
61 | 218 |
             String ret = null;
62 | 218 |
             final int pos = fileName.lastIndexOf(".");
63 | 218 |
             if (pos >= 0) {
64 | 209 |
                 ret = fileName.substring(pos + 1, fileName.length()).toLowerCase();
65 |  |
             }
66 | 218 |
             return ret;
67 |  |
         }
68 |  |
69 |  |
         /**
70 |  |
          * Deletes a file. If the File is a directory it will recursively delete the
71 |  |
          * contents.
72 |  |
          *
73 |  |
          * @param file the File to delete
74 |  |
          * @throws IOException is thrown if the file could not be deleted
75 |  |
          */
76 |  |
         public static void delete(File file) throws IOException {
77 | 18 |
             if (file.isDirectory()) {
78 | 16 |
                 for (File c : file.listFiles()) {
79 | 14 |
                     delete(c);
80 |  |
                 }
81 |  |
             }
82 | 18 |
             if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
83 | 0 |
                 throw new FileNotFoundException("Failed to delete file: " + file);
84 |  |
             }
85 |  |
             /* else {
86 |  |
              //delete on exit was a bad idea. if for some reason the file can't be deleted
87 |  |
              // this will cause a newly constructed file to be deleted and a subsequent run may fail.
88 |  |
              // still not sure why a file fails to be deleted, but can be overwritten... odd.
89 |  |
              file.deleteOnExit();
90 |  |
              }*/
91 | 18 |
         }
92 |  |
93 |  |
         /**
94 |  |
          * Returns the data directory. If a path was specified in
95 |  |
          * dependencycheck.properties or was specified using the Settings object,
96 |  |
          * and the path exists, that path will be returned as a File object. If it
97 |  |
          * does not exist, then a File object will be created based on the file
98 |  |
          * location of the JAR containing the specified class.
99 |  |
          *
100 |  |
          * @param configuredFilePath the configured relative or absolute path
101 |  |
          * @param clazz the class whos path will be resolved
102 |  |
          * @return a File object
103 |  |
          * @throws IOException is thrown if the path could not be decoded
104 |  |
          * @deprecated This method should no longer be used. See the implementation
105 |  |
          * in dependency-check-cli/App.java to see how the data directory should be
106 |  |
          * set.
107 |  |
          */
108 |  |
         @java.lang.Deprecated
109 |  |
         public static File getDataDirectory(String configuredFilePath, Class clazz) throws IOException {
110 | 0 |
             final File file = new File(configuredFilePath);
111 | 0 |
             if (file.isDirectory() && file.canWrite()) {
112 | 0 |
                 return new File(file.getCanonicalPath());
113 |  |
             } else {
114 | 0 |
                 final File exePath = getPathToJar(clazz);
115 | 0 |
                 return new File(exePath, configuredFilePath);
116 |  |
             }
117 |  |
         }
118 |  |
119 |  |
         /**
120 |  |
          * Retrieves the physical path to the parent directory containing the
121 |  |
          * provided class. For example, if a JAR file contained a class
122 |  |
          * org.something.clazz this method would return the parent directory of the
123 |  |
          * JAR file.
124 |  |
          *
125 |  |
          * @param clazz the class to determine the parent directory of
126 |  |
          * @return the parent directory of the file containing the specified class.
127 |  |
          * @throws UnsupportedEncodingException thrown if UTF-8 is not supported.
128 |  |
          * @deprecated this should no longer be used.
129 |  |
          */
130 |  |
         @java.lang.Deprecated
131 |  |
         public static File getPathToJar(Class clazz) throws UnsupportedEncodingException {
132 | 0 |
             final String filePath = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
133 | 0 |
             final String decodedPath = URLDecoder.decode(filePath, "UTF-8");
134 | 0 |
             final File jarPath = new File(decodedPath);
135 | 0 |
             return jarPath.getParentFile();
136 |  |
         }
137 |  |
138 |  |
         /**
139 |  |
          * Extracts the contents of an archive into the specified directory.
140 |  |
          *
141 |  |
          * @param archive an archive file such as a WAR or EAR
142 |  |
          * @param extractTo a directory to extract the contents to
143 |  |
          * @throws ExtractionException thrown if an exception occurs while
144 |  |
          * extracting the files
145 |  |
          */
146 |  |
         public static void extractFiles(File archive, File extractTo) throws ExtractionException {
147 | 1 |
             extractFiles(archive, extractTo, null);
148 | 1 |
         }
149 |  |
150 |  |
         /**
151 |  |
          * Extracts the contents of an archive into the specified directory. The
152 |  |
          * files are only extracted if they are supported by the analyzers loaded
153 |  |
          * into the specified engine. If the engine is specified as null then all
154 |  |
          * files are extracted.
155 |  |
          *
156 |  |
          * @param archive an archive file such as a WAR or EAR
157 |  |
          * @param extractTo a directory to extract the contents to
158 |  |
          * @param engine the scanning engine
159 |  |
          * @throws ExtractionException thrown if there is an error extracting the
160 |  |
          * files
161 |  |
          */
162 |  |
         public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException {
163 | 1 |
             if (archive == null || extractTo == null) {
164 | 0 |
                 return;
165 |  |
             }
166 |  |
167 | 1 |
             FileInputStream fis = null;
168 | 1 |
             ZipInputStream zis = null;
169 |  |
170 |  |
             try {
171 | 1 |
                 fis = new FileInputStream(archive);
172 | 0 |
             } catch (FileNotFoundException ex) {
173 | 0 |
                 Logger.getLogger(FileUtils.class.getName()).log(Level.INFO, null, ex);
174 | 0 |
                 throw new ExtractionException("Archive file was not found.", ex);
175 | 1 |
             }
176 | 1 |
             zis = new ZipInputStream(new BufferedInputStream(fis));
177 |  |
             ZipEntry entry;
178 |  |
             try {
179 | 18 |
                 while ((entry = zis.getNextEntry()) != null) {
180 | 17 |
                     if (entry.isDirectory()) {
181 | 2 |
                         final File d = new File(extractTo, entry.getName());
182 | 2 |
                         if (!d.exists() && !d.mkdirs()) {
183 | 0 |
                             final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
184 | 0 |
                             throw new ExtractionException(msg);
185 |  |
                         }
186 | 2 |
                     } else {
187 | 15 |
                         final File file = new File(extractTo, entry.getName());
188 | 15 |
                         final String ext = getFileExtension(file.getName());
189 | 15 |
                         if (engine == null || engine.supportsExtension(ext)) {
190 | 15 |
                             BufferedOutputStream bos = null;
191 |  |
                             FileOutputStream fos;
192 |  |
                             try {
193 | 15 |
                                 fos = new FileOutputStream(file);
194 | 15 |
                                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
195 |  |
                                 int count;
196 | 15 |
                                 final byte data[] = new byte[BUFFER_SIZE];
197 | 91875 |
                                 while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
198 | 91860 |
                                     bos.write(data, 0, count);
199 |  |
                                 }
200 | 15 |
                                 bos.flush();
201 | 0 |
                             } catch (FileNotFoundException ex) {
202 | 0 |
                                 Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, null, ex);
203 | 0 |
                                 final String msg = String.format("Unable to find file '%s'.", file.getName());
204 | 0 |
                                 throw new ExtractionException(msg, ex);
205 | 0 |
                             } catch (IOException ex) {
206 | 0 |
                                 Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, null, ex);
207 | 0 |
                                 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
208 | 0 |
                                 throw new ExtractionException(msg, ex);
209 |  |
                             } finally {
210 | 15 |
                                 if (bos != null) {
211 |  |
                                     try {
212 | 15 |
                                         bos.close();
213 | 0 |
                                     } catch (IOException ex) {
214 | 0 |
                                         Logger.getLogger(FileUtils.class.getName()).log(Level.FINEST, null, ex);
215 | 15 |
                                     }
216 |  |
                                 }
217 |  |
                             }
218 |  |
                         }
219 | 15 |
                     }
220 |  |
                 }
221 | 0 |
             } catch (IOException ex) {
222 | 0 |
                 final String msg = String.format("Exception reading archive '%s'.", archive.getName());
223 | 0 |
                 Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, msg, ex);
224 | 0 |
                 throw new ExtractionException(msg, ex);
225 |  |
             } finally {
226 | 0 |
                 try {
227 | 1 |
                     zis.close();
228 | 0 |
                 } catch (IOException ex) {
229 | 0 |
                     Logger.getLogger(FileUtils.class.getName()).log(Level.FINEST, null, ex);
230 | 1 |
                 }
231 | 0 |
             }
232 | 1 |
         }
233 |  |
     }