package org.limewire.util;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import junit.framework.Test;
public class CommonUtilsTest extends BaseTestCase {
public CommonUtilsTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(CommonUtilsTest.class);
}
/**
* Test the method for copying files from jars to disk.
*/
public void testCommonUtilsCopyResourceFile() throws Exception {
File newResourceFile = File.createTempFile("copy", "test");
newResourceFile.delete();
newResourceFile.deleteOnExit();
String fileName = "org/apache/commons/logging/Log.class";
URL url = ClassLoader.getSystemResource(fileName);
// Hack out the jarfile location -- strip off jar:file: from beginning, and !/<name> from end
String jarPath = url.toString().substring("jar:file:".length(), url.toString().length() - fileName.length() - 2);
File jarFile = new File(jarPath);
if(!jarFile.isFile())
fail("jar not located");
JarFile jar = new JarFile(jarFile);
JarEntry entry = jar.getJarEntry(fileName);
long entrySize = entry.getSize();
CommonUtils.copyResourceFile(fileName, newResourceFile, false);
assertEquals("size of file in jar should equal size on disk",
entrySize, newResourceFile.length());
newResourceFile.delete();
}
/**
* Tests that the method for converting file name strings to use
* only cross-platform characters works correctly.
*/
public void testCommonUtilsConvertFileName() throws Exception {
char[] illegalChars =
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_ANY_OS");
char[] illegalCharsUnix =
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_UNIX");
char[] illegalCharsWindows =
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_WINDOWS");
runCharTest(illegalChars);
if(OSUtils.isUnix()) {
runCharTest(illegalCharsUnix);
}
if(OSUtils.isWindows()) {
runCharTest(illegalCharsWindows);
}
// now, test really long strings to make sure they're truncated.
String testStr = "FPJWJIEJFFJSFHIUHBUNCENCNUIEHCEHCEHUCIEBCUHEUHULHULHLH"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ"+
"JFDHCIOSHCIOSJCIODJSKJFDSJFKSLDHFUIOSHFUDSBUBBUIBCUDISLBCLSDBFKSCLJ";
assertGreaterThan("string should be longer", 300, testStr.length());
testStr = CommonUtils.convertFileName(testStr);
assertEquals("unexpected string length", 180, testStr.length());
// test conversion with an extension.
StringBuffer twoHundred = new StringBuffer(200);
for(int i = 0; i < 200; i++) twoHundred.append("a");
String withExt = twoHundred + ".zip";
String withBigExt = twoHundred.substring(0, 170) + ".ziiiiiiiiiiiiiip";
String testOne = CommonUtils.convertFileName(withExt);
String testTwo = CommonUtils.convertFileName(withBigExt);
String expectedOne = twoHundred.substring(0, 176) + ".zip";
String expectedTwo = twoHundred.substring(0, 169) + ".ziiiiiiiii";
assertEquals("unexpected length1", expectedOne.length(), testOne.length());
assertEquals("unexpected conversion1", expectedOne, testOne);
assertEquals("unexpected length2", expectedTwo.length(), testTwo.length());
assertEquals("unexpected conversion2", expectedTwo, testTwo);
}
public void testConvertFileNameWithUnicodeInput() throws Exception {
String fileSystem = "\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0";
String converted = CommonUtils.convertFileName(fileSystem);
assertEquals(180, converted.getBytes(Charset.defaultCharset().name()).length);
}
public void testConvertFileNameWithExtensionAndUnicodeInput() throws Exception {
String[] fileSystems = {
"\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7.\u30b9\u30c6\u30e0",
"\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0.txt",
"\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4.\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0",
};
for (String fileSystem : fileSystems) {
String converted = CommonUtils.convertFileName(fileSystem);
assertLessThanOrEquals(fileSystem + " not 180 bytes long",
180, converted.getBytes(Charset.defaultCharset().name()).length);
// still has extension
assertTrue(converted.contains("."));
// extension is substring of original extension
assertTrue(fileSystem.substring(fileSystem.indexOf('.')).contains(converted.substring(converted.indexOf('.'))));
}
// test identity for small end substrings
for (String fileSystem : fileSystems) {
String halfed = fileSystem.substring(fileSystem.length() - 40);
String converted = CommonUtils.convertFileName(halfed);
assertEquals(halfed, converted);
}
// add illegal characters at various places and ensure
// maximum length is respected
for (char[] illegalChars : new char[][] {
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_ANY_OS"),
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_UNIX"),
(char[])PrivilegedAccessor.getValue(CommonUtils.class,
"ILLEGAL_CHARS_WINDOWS")
}) {
for (String fileSystem: fileSystems) {
char[] fileNameChars = fileSystem.toCharArray();
for (char illegalChar : illegalChars) {
fileNameChars[(int)(Math.random() * (fileNameChars.length - 1))] = illegalChar;
String converted = CommonUtils.convertFileName(new String(fileNameChars));
assertLessThanOrEquals(180, converted.getBytes(Charset.defaultCharset().name()).length);
}
}
}
}
/**
* Tests that IO exception is thrown if parent dir's byte representation
* already exceeds max path length, but its char representation does not.
*/
public void testConvertFileNameDiscardsTooLongParentPaths() throws Exception {
char c = '\u30d5';
char[] dirName = new char[OSUtils.getMaxPathLength() - 10];
Arrays.fill(dirName, c);
dirName[0] = '/';
String dir = new String(dirName);
assertEquals(OSUtils.getMaxPathLength() - 10, dir.length());
assertGreaterThan(OSUtils.getMaxPathLength(), dir.getBytes(Charset.defaultCharset().name()).length);
try {
CommonUtils.convertFileName(new File(dir), "somename");
fail("Should have thrown IOException");
} catch (IOException ie) {
}
}
public void testConvertFileNameIdentity() throws CharacterCodingException {
assertEquals("test", CommonUtils.convertFileName("test"));
assertEquals("test.me", CommonUtils.convertFileName("test.me"));
assertEquals("Test me with Spaces!.meee", CommonUtils.convertFileName("Test me with Spaces!.meee"));
assertEquals("long.extension", CommonUtils.convertFileName("long.extension"));
}
public void testConvertFileNameWithParentDir() throws IOException {
File dir = new File("/short/dir/");
assertEquals("test", CommonUtils.convertFileName(dir, "test"));
assertEquals("test.me", CommonUtils.convertFileName(dir, "test.me"));
assertEquals("Test me with Spaces!.meee", CommonUtils.convertFileName(dir, "Test me with Spaces!.meee"));
assertEquals("long.extension", CommonUtils.convertFileName(dir, "long.extension"));
char[] dirName = new char[OSUtils.getMaxPathLength()];
Arrays.fill(dirName, 'a');
for (int i = 0; i < dirName.length; i += 254) {
dirName[i] = '/';
}
dir = new File(new String(dirName));
try {
CommonUtils.convertFileName(dir, "lbkajdf ;alksdf");
fail("IOException expected for too long parent dir");
} catch (IOException iee) {
}
dir = new File(new String(dirName, 0, dirName.length - 2));
assertEquals(1, CommonUtils.convertFileName(dir, "blah, blhalksd").getBytes(Charset.defaultCharset().name()).length);
dir = new File(new String(dirName, 0, dirName.length - 5));
assertEquals("1234", CommonUtils.convertFileName(dir, "12345"));
}
public void testMaxBytesParameter() throws Exception {
assertEquals("1", CommonUtils.convertFileName("12345", 1));
assertEquals("12", CommonUtils.convertFileName("12345", 2));
try {
CommonUtils.convertFileName("1345", 0);
fail("No IAE thrown");
} catch (IllegalArgumentException iae) {
}
}
public void testMaxBytesEncoderBailsOut() throws Exception {
String fileSystem = "\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0";
try {
CommonUtils.getMaxBytes(fileSystem, 16, Charset.forName("ascii"));
fail("coding exception expected");
} catch (CharacterCodingException cce) {
}
}
public void testConvertFileNameReturnsTooLongFileNameWhenExtensionIsLongerThanMaxBytes() throws Exception {
String converted = CommonUtils.convertFileName("hello.world", 4);
assertLessThanOrEquals(4, converted.getBytes(Charset.defaultCharset().name()).length);
}
public void testNoTrailingSeparator() throws IOException {
File tmpFile = File.createTempFile("tmpfile", "file");
File tmpDir = tmpFile.getParentFile();
tmpFile.delete();
assertFalse(tmpDir.getAbsolutePath().endsWith(File.separator));
}
/**
* Helper method for testing illegal character conversion method.
*/
private void runCharTest(char[] illegalChars) throws Exception {
String test = "test";
String correctResult = "test_";
for (char illegalChar : illegalChars) {
String curTest = CommonUtils.convertFileName(test + illegalChar);
assertEquals("illegal char: " + illegalChar + " not replaced correctly",
correctResult, curTest);
}
}
}