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