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; } }