20
20
import com .j256 .simplemagic .ContentInfo ;
21
21
import com .j256 .simplemagic .ContentInfoUtil ;
22
22
import com .j256 .simplemagic .ContentType ;
23
- import java .io .ByteArrayInputStream ;
24
23
import java .io .IOException ;
25
24
import java .io .InputStream ;
26
25
import java .nio .file .FileVisitResult ;
@@ -58,30 +57,23 @@ public class FileTypeMagicUtil implements ContentInfoUtil.ErrorCallBack {
58
57
public static void assertConfigSetFolderLegal (Path confPath ) throws IOException {
59
58
Files .walkFileTree (
60
59
confPath ,
61
- new SimpleFileVisitor <Path >() {
60
+ new SimpleFileVisitor <>() {
62
61
@ Override
63
- public FileVisitResult visitFile (Path file , BasicFileAttributes attrs )
64
- throws IOException {
65
- // Read first 100 bytes of the file to determine the mime type
66
- try (InputStream fileStream = Files .newInputStream (file )) {
67
- byte [] bytes = new byte [100 ];
68
- fileStream .read (bytes );
69
- if (FileTypeMagicUtil .isFileForbiddenInConfigset (bytes )) {
70
- throw new SolrException (
71
- SolrException .ErrorCode .BAD_REQUEST ,
72
- String .format (
73
- Locale .ROOT ,
74
- "Not uploading file %s to configset, as it matched the MAGIC signature of a forbidden mime type %s" ,
75
- file ,
76
- FileTypeMagicUtil .INSTANCE .guessMimeType (bytes )));
77
- }
78
- return FileVisitResult .CONTINUE ;
62
+ public FileVisitResult visitFile (Path file , BasicFileAttributes attrs ) {
63
+ if (FileTypeMagicUtil .isFileForbiddenInConfigset (file )) {
64
+ throw new SolrException (
65
+ SolrException .ErrorCode .BAD_REQUEST ,
66
+ String .format (
67
+ Locale .ROOT ,
68
+ "Not uploading file %s to configset, as it matched the MAGIC signature of a forbidden mime type %s" ,
69
+ file ,
70
+ FileTypeMagicUtil .INSTANCE .guessMimeType (file )));
79
71
}
72
+ return FileVisitResult .CONTINUE ;
80
73
}
81
74
82
75
@ Override
83
- public FileVisitResult preVisitDirectory (Path dir , BasicFileAttributes attrs )
84
- throws IOException {
76
+ public FileVisitResult preVisitDirectory (Path dir , BasicFileAttributes attrs ) {
85
77
if (SKIP_FOLDERS .contains (dir .getFileName ().toString ()))
86
78
return FileVisitResult .SKIP_SUBTREE ;
87
79
@@ -90,19 +82,29 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
90
82
});
91
83
}
92
84
85
+ /**
86
+ * Guess the mime type of file based on its magic number.
87
+ *
88
+ * @param file file to check
89
+ * @return string with content-type or "application/octet-stream" if unknown
90
+ */
91
+ public String guessMimeType (Path file ) {
92
+ try {
93
+ return guessTypeFallbackToOctetStream (util .findMatch (file .toFile ()));
94
+ } catch (IOException e ) {
95
+ throw new SolrException (SolrException .ErrorCode .SERVER_ERROR , e );
96
+ }
97
+ }
98
+
93
99
/**
94
100
* Guess the mime type of file based on its magic number.
95
101
*
96
102
* @param stream input stream of the file
97
103
* @return string with content-type or "application/octet-stream" if unknown
98
104
*/
99
- public String guessMimeType (InputStream stream ) {
105
+ String guessMimeType (InputStream stream ) {
100
106
try {
101
- ContentInfo info = util .findMatch (stream );
102
- if (info == null ) {
103
- return ContentType .OTHER .getMimeType ();
104
- }
105
- return info .getContentType ().getMimeType ();
107
+ return guessTypeFallbackToOctetStream (util .findMatch (stream ));
106
108
} catch (IOException e ) {
107
109
throw new SolrException (SolrException .ErrorCode .SERVER_ERROR , e );
108
110
}
@@ -115,7 +117,7 @@ public String guessMimeType(InputStream stream) {
115
117
* @return string with content-type or "application/octet-stream" if unknown
116
118
*/
117
119
public String guessMimeType (byte [] bytes ) {
118
- return guessMimeType ( new ByteArrayInputStream (bytes ));
120
+ return guessTypeFallbackToOctetStream ( util . findMatch (bytes ));
119
121
}
120
122
121
123
@ Override
@@ -126,6 +128,31 @@ public void error(String line, String details, Exception e) {
126
128
e );
127
129
}
128
130
131
+ /**
132
+ * Determine forbidden file type based on magic bytes matching of the file itself. Forbidden types
133
+ * are:
134
+ *
135
+ * <ul>
136
+ * <li><code>application/x-java-applet</code>: java class file
137
+ * <li><code>application/zip</code>: jar or zip archives
138
+ * <li><code>application/x-tar</code>: tar archives
139
+ * <li><code>text/x-shellscript</code>: shell or bash script
140
+ * </ul>
141
+ *
142
+ * @param file file to check
143
+ * @return true if file is among the forbidden mime-types
144
+ */
145
+ public static boolean isFileForbiddenInConfigset (Path file ) {
146
+ try (InputStream fileStream = Files .newInputStream (file )) {
147
+ return isFileForbiddenInConfigset (fileStream );
148
+ } catch (IOException e ) {
149
+ throw new SolrException (
150
+ SolrException .ErrorCode .SERVER_ERROR ,
151
+ String .format (Locale .ROOT , "Error reading file %s" , file ),
152
+ e );
153
+ }
154
+ }
155
+
129
156
/**
130
157
* Determine forbidden file type based on magic bytes matching of the file itself. Forbidden types
131
158
* are:
@@ -140,7 +167,7 @@ public void error(String line, String details, Exception e) {
140
167
* @param fileStream stream from the file content
141
168
* @return true if file is among the forbidden mime-types
142
169
*/
143
- public static boolean isFileForbiddenInConfigset (InputStream fileStream ) {
170
+ static boolean isFileForbiddenInConfigset (InputStream fileStream ) {
144
171
return forbiddenTypes .contains (FileTypeMagicUtil .INSTANCE .guessMimeType (fileStream ));
145
172
}
146
173
@@ -153,7 +180,7 @@ public static boolean isFileForbiddenInConfigset(InputStream fileStream) {
153
180
public static boolean isFileForbiddenInConfigset (byte [] bytes ) {
154
181
if (bytes == null || bytes .length == 0 )
155
182
return false ; // A ZK znode may be a folder with no content
156
- return isFileForbiddenInConfigset ( new ByteArrayInputStream (bytes ));
183
+ return forbiddenTypes . contains ( FileTypeMagicUtil . INSTANCE . guessMimeType (bytes ));
157
184
}
158
185
159
186
private static final Set <String > forbiddenTypes =
@@ -163,4 +190,12 @@ public static boolean isFileForbiddenInConfigset(byte[] bytes) {
163
190
"solr.configset.upload.mimetypes.forbidden" ,
164
191
"application/x-java-applet,application/zip,application/x-tar,text/x-shellscript" )
165
192
.split ("," )));
193
+
194
+ private String guessTypeFallbackToOctetStream (ContentInfo contentInfo ) {
195
+ if (contentInfo == null ) {
196
+ return ContentType .OTHER .getMimeType ();
197
+ } else {
198
+ return contentInfo .getContentType ().getMimeType ();
199
+ }
200
+ }
166
201
}
0 commit comments