Author: sebb
Date: Wed Jan 14 23:09:12 2015
New Revision: 1651873
URL: http://svn.apache.org/r1651873
Log:
VALIDATOR-356 IDN.toASCII drops trailing dot in Java 6 & 7
Modified:
commons/proper/validator/trunk/src/changes/changes.xml
commons/proper/validator/trunk/src/main/java/org/apache/commons/validator/routines/DomainValidator.java
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/DomainValidatorTest.java
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
Modified: commons/proper/validator/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/validator/trunk/src/changes/changes.xml?rev=1651873&r1=1651872&r2=1651873&view=diff
==============================================================================
--- commons/proper/validator/trunk/src/changes/changes.xml (original)
+++ commons/proper/validator/trunk/src/changes/changes.xml Wed Jan 14 23:09:12
2015
@@ -43,6 +43,9 @@ The <action> type attribute can be add,u
<body>
<release version="1.5.0" date="tba" description="tba">
+ <action issue="VALIDATOR-356" dev="seb" type="fix" >
+ IDN.toASCII drops trailing dot in Java 6 & 7
+ </action>
<action issue="VALIDATOR-355" dev="britter" type="update" >
Update to Java 6
</action>
Modified:
commons/proper/validator/trunk/src/main/java/org/apache/commons/validator/routines/DomainValidator.java
URL:
http://svn.apache.org/viewvc/commons/proper/validator/trunk/src/main/java/org/apache/commons/validator/routines/DomainValidator.java?rev=1651873&r1=1651872&r2=1651873&view=diff
==============================================================================
---
commons/proper/validator/trunk/src/main/java/org/apache/commons/validator/routines/DomainValidator.java
(original)
+++
commons/proper/validator/trunk/src/main/java/org/apache/commons/validator/routines/DomainValidator.java
Wed Jan 14 23:09:12 2015
@@ -1085,16 +1085,46 @@ public class DomainValidator implements
*/
// Needed by UrlValidator
static String unicodeToASCII(String input) {
- if (isOnlyASCII(input)) { // TODO temporary hack to work round
IDN.toASCII bug
+ if (isOnlyASCII(input)) { // skip possibly expensive processing
return input;
}
try {
- return IDN.toASCII(input);
+ final String ascii = IDN.toASCII(input);
+ if (IDNBUGHOLDER.IDN_TOASCII_PRESERVES_TRAILING_DOTS) {
+ return ascii;
+ }
+ final int length = input.length();
+ if (length == 0) {// check there is a last character
+ return input;
+ }
+// RFC3490 3.1. 1)
+// Whenever dots are used as label separators, the following
+// characters MUST be recognized as dots: U+002E (full stop), U+3002
+// (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61
+// (halfwidth ideographic full stop).
+ char lastChar = input.charAt(length-1);// fetch original last char
+ switch(lastChar) {
+ case '\u002E': // "." full stop
+ case '\u3002': // ideographic full stop
+ case '\uFF0E': // fullwidth full stop
+ case '\uFF61': // halfwidth ideographic full stop
+ return ascii + "."; // restore the missing stop
+ default:
+ return ascii;
+ }
} catch (IllegalArgumentException e) { // input is not valid
return input;
}
}
+ private static class IDNBUGHOLDER {
+ private static boolean keepsTrailingDot() {
+ final String input = "a."; // must be a valid name
+ return input.equals(IDN.toASCII(input));
+ }
+ private static final boolean IDN_TOASCII_PRESERVES_TRAILING_DOTS =
keepsTrailingDot();
+ }
+
/*
* Check if input contains only ASCII
* Treats null as all ASCII
Modified:
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/DomainValidatorTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/DomainValidatorTest.java?rev=1651873&r1=1651872&r2=1651873&view=diff
==============================================================================
---
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/DomainValidatorTest.java
(original)
+++
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/DomainValidatorTest.java
Wed Jan 14 23:09:12 2015
@@ -208,6 +208,67 @@ public class DomainValidatorTest extends
assertFalse("254 chars domain should fail",
validator.isValidDomainSyntax(longDomain+"x"));
}
+ // Check that IDN.toASCII behaves as it should (when wrapped by
DomainValidator.unicodeToASCII)
+ // Tests show that method incorrectly trims a trailing "." character
+ public void testUnicodeToASCII() {
+ String[] asciidots = {
+ "",
+ ",",
+ ".", // fails IDN.toASCII, but should pass wrapped version
+ "a.", // ditto
+ "a.b",
+ "a..b",
+ "a...b",
+ ".a",
+ "..a",
+ };
+ for(String s : asciidots) {
+ assertEquals(s,DomainValidator.unicodeToASCII(s));
+ }
+ // RFC3490 3.1. 1)
+// Whenever dots are used as label separators, the following
+// characters MUST be recognized as dots: U+002E (full stop), U+3002
+// (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61
+// (halfwidth ideographic full stop).
+ final String otherDots[][] = {
+ {"b\u3002", "b.",},
+ {"b\uFF0E", "b.",},
+ {"b\uFF61", "b.",},
+ {"\u3002", ".",},
+ {"\uFF0E", ".",},
+ {"\uFF61", ".",},
+ };
+ for(String s[] : otherDots) {
+ assertEquals(s[1],DomainValidator.unicodeToASCII(s[0]));
+ }
+ }
+
+ // Check if IDN.toASCII is broken or not
+ public void testIsIDNtoASCIIBroken() {
+ System.out.println(">>DomainValidatorTest.testIsIDNtoASCIIBroken()");
+ final String input = ".";
+ final boolean ok = input.equals(IDN.toASCII(input));
+ System.out.println("IDN.toASCII is " + (ok? "OK" : "BROKEN"));
+ String props[] = {
+ "java.version", // Java Runtime Environment version
+ "java.vendor", // Java Runtime Environment vendor
+ "java.vm.specification.version", // Java Virtual Machine
specification version
+ "java.vm.specification.vendor", // Java Virtual Machine
specification vendor
+ "java.vm.specification.name", // Java Virtual Machine specification
name
+ "java.vm.version", // Java Virtual Machine implementation version
+ "java.vm.vendor", // Java Virtual Machine implementation vendor
+ "java.vm.name", // Java Virtual Machine implementation name
+ "java.specification.version", // Java Runtime Environment
specification version
+ "java.specification.vendor", // Java Runtime Environment
specification vendor
+ "java.specification.name", // Java Runtime Environment specification
name
+ "java.class.version", // Java class format version number
+ };
+ for(String t : props) {
+ System.out.println(t + "=" + System.getProperty(t));
+ }
+ System.out.println("<<DomainValidatorTest.testIsIDNtoASCIIBroken()");
+ }
+
// Check array is sorted and is lower-case
public void test_INFRASTRUCTURE_TLDS_sortedAndLowerCase() throws Exception
{
final boolean sorted = isSortedLowerCase("INFRASTRUCTURE_TLDS");
Modified:
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java?rev=1651873&r1=1651872&r2=1651873&view=diff
==============================================================================
---
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
(original)
+++
commons/proper/validator/trunk/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java
Wed Jan 14 23:09:12 2015
@@ -295,6 +295,15 @@ public class UrlValidatorTest extends Te
assertFalse(urlValidator.isValid("http://www.cnn.invalid./")); //
check . does not affect invalid domains
}
+ public void testValidator339IDN(){
+ UrlValidator urlValidator = new UrlValidator();
+
assertTrue(urlValidator.isValid("http://пÑезиденÑ.ÑÑ/WORLD/?hpt=sitenav"));
// without
+
assertTrue(urlValidator.isValid("http://пÑезиденÑ.ÑÑ./WORLD/?hpt=sitenav"));
// with
+
assertFalse(urlValidator.isValid("http://пÑезиденÑ.ÑÑ..../")); //
very dotty
+
assertFalse(urlValidator.isValid("http://пÑезиденÑ.ÑÑ.../")); //
triply dotty
+
assertFalse(urlValidator.isValid("http://пÑезиденÑ.ÑÑ../")); //
doubly dotty
+ }
+
public void testValidator342(){
UrlValidator urlValidator = new UrlValidator();
assertTrue(urlValidator.isValid("http://example.rocks/"));