Skip to content

Commit

Permalink
Use PropertyResourceBundle in test suite and validate .properties
Browse files Browse the repository at this point in the history
… files are not both valid UTF-8 and valid ISO-8859-1 (#433)

Co-authored-by: Basil Crow <[email protected]>
  • Loading branch information
timja and basil authored May 10, 2022
1 parent 11e83ae commit 86627ac
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion src/main/java/org/jvnet/hudson/test/PropertiesTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,22 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.io.IOUtils;

import static org.jvnet.hudson.test.JellyTestSuiteBuilder.scan;

/**
Expand Down Expand Up @@ -66,11 +78,43 @@ public synchronized Object put(Object key, Object value) {
return null;
}
};

byte[] contents = IOUtils.toByteArray(resource);
if (!isEncoded(contents, StandardCharsets.US_ASCII)) {
boolean isUtf8 = isEncoded(contents, StandardCharsets.UTF_8);
boolean isIso88591 = isEncoded(contents, StandardCharsets.ISO_8859_1);
if (isUtf8 && isIso88591) {
throw new AssertionError(resource + " is valid UTF-8 and valid ISO-8859-1. To avoid problems when auto-detecting the encoding, use the lowest common denominator of ASCII encoding and express non-ASCII characters with escape sequences using a tool like `native2ascii`.");
}
}

try (InputStream is = resource.openStream()) {
props.load(is);
PropertyResourceBundle propertyResourceBundle = new PropertyResourceBundle(is);
Enumeration<String> keys = propertyResourceBundle.getKeys();
// TODO Java 9+ can use 'asIterator' and get rid of below collections conversion
List<String> keysAsSaneType = Collections.list(keys);

for (String localKey : keysAsSaneType) {
String value = propertyResourceBundle.getString(localKey);
props.setProperty(localKey, value);
}
}
}

}

private static boolean isEncoded(byte[] bytes, Charset charset) {
CharsetDecoder decoder = charset.newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
ByteBuffer buffer = ByteBuffer.wrap(bytes);

try {
decoder.decode(buffer);
return true;
} catch (CharacterCodingException e) {
return false;
}
}

}

0 comments on commit 86627ac

Please sign in to comment.