Skip to content

Commit 8071b23

Browse files
author
Brian Burkhalter
committed
8287237: (fs) Files.probeContentType returns null if filename contains hash mark on Linux
Reviewed-by: rriggs, jpai, vtewari
1 parent 774928f commit 8071b23

File tree

2 files changed

+64
-26
lines changed

2 files changed

+64
-26
lines changed

src/java.base/share/classes/sun/net/www/MimeTable.java

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,27 @@
2727

2828
import jdk.internal.util.StaticProperty;
2929

30-
import java.io.*;
30+
import java.io.File;
31+
import java.io.FileInputStream;
32+
import java.io.FileNotFoundException;
33+
import java.io.FileOutputStream;
34+
import java.io.InputStream;
35+
import java.io.IOException;
3136
import java.net.FileNameMap;
32-
import java.util.Hashtable;
3337
import java.util.Enumeration;
38+
import java.util.Hashtable;
3439
import java.util.Properties;
3540
import java.util.StringTokenizer;
3641

3742
public class MimeTable implements FileNameMap {
43+
/** Hash mark introducing a URI fragment */
44+
private static final int HASH_MARK = '#';
45+
3846
/** Keyed by content type, returns MimeEntries */
39-
private Hashtable<String, MimeEntry> entries
40-
= new Hashtable<>();
47+
private Hashtable<String, MimeEntry> entries = new Hashtable<>();
4148

4249
/** Keyed by file extension (with the .), returns MimeEntries */
43-
private Hashtable<String, MimeEntry> extensionMap
44-
= new Hashtable<>();
50+
private Hashtable<String, MimeEntry> extensionMap = new Hashtable<>();
4551

4652
// Will be reset if in the platform-specific data file
4753
@SuppressWarnings("removal")
@@ -84,9 +90,6 @@ public static MimeTable getDefaultTable() {
8490
return DefaultInstanceHolder.defaultInstance;
8591
}
8692

87-
/**
88-
*
89-
*/
9093
public static FileNameMap loadTable() {
9194
MimeTable mt = getDefaultTable();
9295
return mt;
@@ -151,30 +154,54 @@ public synchronized MimeEntry find(String type) {
151154
}
152155

153156
/**
154-
* Locate a MimeEntry by the file extension that has been associated
155-
* with it. Parses general file names, and URLs.
157+
* Extracts the file extension and uses it to look up the entry.
156158
*/
157-
public MimeEntry findByFileName(String fname) {
158-
String ext = "";
159-
160-
int i = fname.lastIndexOf('#');
161-
162-
if (i > 0) {
163-
fname = fname.substring(0, i - 1);
164-
}
165-
166-
i = fname.lastIndexOf('.');
159+
private MimeEntry findViaFileExtension(String fname) {
160+
int i = fname.lastIndexOf('.');
167161
// REMIND: OS specific delimiters appear here
168162
i = Math.max(i, fname.lastIndexOf('/'));
169163
i = Math.max(i, fname.lastIndexOf('?'));
170164

165+
String ext = "";
171166
if (i != -1 && fname.charAt(i) == '.') {
172167
ext = fname.substring(i).toLowerCase();
173168
}
174169

175170
return findByExt(ext);
176171
}
177172

173+
/**
174+
* Locate a MimeEntry by its associated file extension.
175+
* Parses general file names, and URLs.
176+
*
177+
* @param fname the file name
178+
*
179+
* @return the MIME entry associated with the file name or {@code null}
180+
*/
181+
public MimeEntry findByFileName(String fname) {
182+
MimeEntry entry = null;
183+
184+
// If an optional fragment introduced by a hash mark is
185+
// present, then strip it and use the prefix
186+
int hashIndex = fname.lastIndexOf(HASH_MARK);
187+
if (hashIndex > 0) {
188+
entry = findViaFileExtension(fname.substring(0, hashIndex));
189+
if (entry != null) {
190+
return entry;
191+
}
192+
}
193+
194+
assert entry == null;
195+
196+
// If either no optional fragment was present, or the entry was not
197+
// found with the fragment stripped, then try again with the full name
198+
if (entry == null) {
199+
entry = findViaFileExtension(fname);
200+
}
201+
202+
return entry;
203+
}
204+
178205
/**
179206
* Locate a MimeEntry by the file extension that has been associated
180207
* with it.

test/jdk/java/nio/file/Files/probeContentType/Basic.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@
2222
*/
2323

2424
/* @test
25-
* @bug 4313887 8129632 8129633 8162624 8146215 8162745 8273655 8274171
25+
* @bug 4313887 8129632 8129633 8162624 8146215 8162745 8273655 8274171 8287237
2626
* @summary Unit test for probeContentType method
2727
* @library ../..
2828
* @build Basic SimpleFileTypeDetector
2929
* @run main/othervm Basic
3030
*/
3131

32-
import java.io.*;
33-
import java.nio.file.*;
32+
import java.io.IOException;
33+
import java.io.OutputStream;
34+
import java.nio.file.Files;
35+
import java.nio.file.Path;
3436
import java.util.List;
3537
import java.util.stream.Stream;
3638

@@ -79,10 +81,10 @@ private static int checkContentTypes(String expected, String actual) {
7981
if (!expected.equals(actual)) {
8082
if (IS_UNIX) {
8183
Path userMimeTypes =
82-
Paths.get(System.getProperty("user.home"), ".mime.types");
84+
Path.of(System.getProperty("user.home"), ".mime.types");
8385
checkMimeTypesFile(userMimeTypes);
8486

85-
Path etcMimeTypes = Paths.get("/etc/mime.types");
87+
Path etcMimeTypes = Path.of("/etc/mime.types");
8688
checkMimeTypesFile(etcMimeTypes);
8789
}
8890

@@ -188,6 +190,15 @@ public static void main(String[] args) throws IOException {
188190
};
189191
failures += checkContentTypes(exTypes);
190192

193+
// Verify type is found when the extension is in a fragment component
194+
Path pathWithFragement = Path.of("SomePathWith#aFragement.png");
195+
String contentType = Files.probeContentType(pathWithFragement);
196+
if (contentType == null || !contentType.equals("image/png")) {
197+
System.err.printf("For %s expected \"png\" but got %s%n",
198+
pathWithFragement, contentType);
199+
failures++;
200+
}
201+
191202
if (failures > 0) {
192203
throw new RuntimeException("Test failed!");
193204
}

0 commit comments

Comments
 (0)