1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.resource.temporary.internal

File DefaultTemporaryResourceStore.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart0.png
83% of files have more coverage

Code metrics

6
35
3
1
119
80
7
0.2
11.67
3
2.33

Classes

Class Line # Actions
DefaultTemporaryResourceStore 52 35 0% 7 44
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.resource.temporary.internal;
21   
22    import java.io.File;
23    import java.io.FileOutputStream;
24    import java.io.IOException;
25    import java.io.InputStream;
26    import java.io.UnsupportedEncodingException;
27    import java.net.URLEncoder;
28    import java.util.ArrayList;
29    import java.util.List;
30   
31    import javax.inject.Inject;
32    import javax.inject.Singleton;
33   
34    import org.apache.commons.io.IOUtils;
35    import org.apache.commons.lang.StringUtils;
36    import org.xwiki.component.annotation.Component;
37    import org.xwiki.environment.Environment;
38    import org.xwiki.model.reference.EntityReference;
39    import org.xwiki.resource.temporary.TemporaryResourceReference;
40    import org.xwiki.resource.temporary.TemporaryResourceStore;
41   
42    /**
43    * Default {@link TemporaryResourceStore} implementation that uses the configured temporary directory.
44    *
45    * @version $Id: 4525d62a46345c96fd67f045f2c7a652cb4cdb5a $
46    * @since 7.4.6
47    * @since 8.2.2
48    * @since 8.3
49    */
50    @Component
51    @Singleton
 
52    public class DefaultTemporaryResourceStore implements TemporaryResourceStore
53    {
54    @Inject
55    private Environment environment;
56   
 
57  0 toggle @Override
58    public File createTemporaryFile(TemporaryResourceReference reference, InputStream content) throws IOException
59    {
60  0 File temporaryFile = getTemporaryFile(reference);
61  0 FileOutputStream fos = null;
62  0 try {
63    // Make sure the parent folders exist.
64  0 temporaryFile.getParentFile().mkdirs();
65  0 fos = new FileOutputStream(temporaryFile);
66  0 temporaryFile.deleteOnExit();
67  0 IOUtils.copy(content, fos);
68    } finally {
69  0 IOUtils.closeQuietly(fos);
70    }
71  0 return temporaryFile;
72    }
73   
 
74  0 toggle @Override
75    public File getTemporaryFile(TemporaryResourceReference reference) throws IOException
76    {
77  0 List<String> segments = new ArrayList<String>();
78  0 segments.add("tmp");
79  0 segments.add(reference.getModuleId());
80  0 int safePathLength = 2;
81  0 if (reference.getOwningEntityReference() != null) {
82  0 for (EntityReference component : reference.getOwningEntityReference().getReversedReferenceChain()) {
83  0 segments.add(component.getName());
84  0 safePathLength++;
85    }
86    }
87  0 if (!reference.getParameters().isEmpty()) {
88  0 segments.add(String.valueOf(reference.getParameters().hashCode()));
89  0 safePathLength++;
90    }
91  0 segments.addAll(reference.getResourcePath());
92  0 String path = StringUtils.join(encode(segments), '/');
93  0 String safePath = StringUtils.join(encode(segments.subList(0, safePathLength)), '/');
94  0 File rootFolder = this.environment.getTemporaryDirectory();
95  0 File safeFolder = new File(rootFolder, safePath);
96  0 File temporaryFile = new File(rootFolder, path);
97   
98    // Make sure the resource path is not relative (e.g. "../../../") and tries to get outside of the safe folder.
99  0 if (!temporaryFile.getAbsolutePath().startsWith(safeFolder.getAbsolutePath())) {
100  0 String resourcePath = StringUtils.join(encode(segments.subList(safePathLength, segments.size())), '/');
101  0 throw new IOException(String.format("Invalid resource path [%s].", resourcePath));
102    }
103   
104  0 return temporaryFile;
105    }
106   
 
107  0 toggle private List<String> encode(List<String> path)
108    {
109  0 List<String> encodedPath = new ArrayList<String>(path.size());
110  0 for (String segment : path) {
111  0 try {
112  0 encodedPath.add(URLEncoder.encode(segment, "UTF-8"));
113    } catch (UnsupportedEncodingException e) {
114    // Should never happen.
115    }
116    }
117  0 return encodedPath;
118    }
119    }