package com.limegroup.gnutella.malware;
import java.io.File;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.limewire.core.settings.FilterSettings;
import org.limewire.inject.LazySingleton;
import org.limewire.util.FileUtils;
import eu.medsea.mimeutil.MimeException;
import eu.medsea.mimeutil.MimeUtil;
/**
* Compares the mime type(s) of a file to its extension to ensure that, if
* the mime type indicates a dangerous file type, the extension indicates
* the same file type. See FileExtensionEncoder for the defined types.
*/
@LazySingleton
class FileExtensionChecker implements DangerousFileChecker {
private final DangerousFileType[] fileTypes;
FileExtensionChecker() {
DangerousFileType[] ft;
try {
String setting = FilterSettings.DANGEROUS_FILE_TYPES.get();
ft = FileExtensionEncoder.decodeSetting(setting);
} catch(IllegalArgumentException e) {
ft = new DangerousFileType[0];
}
fileTypes = ft;
}
/**
* Returns the number of dangerous file types the checker knows about.
* Package access for testing.
*/
protected int getNumKnownTypes() {
return fileTypes.length;
}
/**
* Returns true if the file's mime type indicates a dangerous type
* but the extension does not.
*/
@Override
public boolean isDangerous(File file) {
Set<String> types = new HashSet<String>();
try {
// The returned objects are MimeTypes - get their String values
for(Object o : MimeUtil.getMimeTypes(file)) {
types.add(o.toString());
}
} catch(MimeException e) {
return false;
}
// Get the extension (empty if there's no extension)
String ext = FileUtils.getFileExtension(file).toLowerCase(Locale.US);
// Check each dangerous file type against the file's mime type(s)
for(DangerousFileType type : fileTypes) {
if(types.contains(type.mimeType)) {
boolean extensionMatchesType = false;
for(String allowed : type.extensions) {
if(ext.equals(allowed)) {
extensionMatchesType = true;
break;
}
}
return !extensionMatchesType;
}
}
return false;
}
}