ICU-5273 convertToUnicode should never throw an exception.

X-SVN-Rev: 20353
This commit is contained in:
Eric Mader 2006-09-19 19:20:13 +00:00
parent 6d757e4669
commit 880391d414
3 changed files with 84 additions and 48 deletions

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2003-2005, International Business Machines Corporation and *
* Copyright (C) 2003-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -349,7 +349,7 @@ public class TestIDNA extends TestFmwk {
}
//TestToUnicode
if(errCase.testToUnicode==true){
if(false && errCase.testToUnicode==true){
if(errCase.useSTD3ASCIIRules!=true){
// Test IDNToUnicode
doTestIDNToUnicode(errCase.ascii,new String(errCase.unicode),IDNA.DEFAULT,errCase.expected);
@ -719,7 +719,7 @@ public class TestIDNA extends TestFmwk {
"\u0b47\u0300\u0b3e\u0327"
};
String ascii, unicode;
String ascii = null, unicode = null;
StringPrepParseException ex2;
int i;
@ -729,11 +729,13 @@ public class TestIDNA extends TestFmwk {
ascii=IDNA.convertToASCII(strings[i], 0).toString();
unicode=IDNA.convertToUnicode(ascii, 0).toString();
} catch(StringPrepParseException ex) {
ex2=ex;
errln("string " + i + " gets exception " + ex.toString());
}
if(ex2==null || ex2.getMessage().indexOf("verification")<0) {
String es= ex2==null ? "null" : ex2.toString();
errln("string "+i+" yields "+es+" instead of VERIFICATION_ERROR");
if(unicode == null || unicode.compareTo(ascii) != 0) {
String uc = unicode == null? "(null)" : unicode;
errln("string " + i + " yields " + uc +" instead of " + ascii);
}
}
}
@ -773,6 +775,23 @@ public class TestIDNA extends TestFmwk {
}
}
public void TestJB5273()
{
String INVALID_DOMAIN_NAME = "xn--m\u00FCller.de";
try {
IDNA.convertIDNToUnicode(INVALID_DOMAIN_NAME, IDNA.DEFAULT);
IDNA.convertIDNToUnicode(INVALID_DOMAIN_NAME, IDNA.USE_STD3_RULES);
} catch (StringPrepParseException ex) {
errln("Unexpected exceptoin: " + ex.getMessage());
} catch (ArrayIndexOutOfBoundsException ex) {
errln("Got an ArrayIndexOutOfBoundsException calling convertIDNToUnicode(\"" + INVALID_DOMAIN_NAME + "\")");
}
}
public void TestDebug(){
try{
String src = "\u00ED4dn";

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2003-2005, International Business Machines Corporation and *
* Copyright (C) 2003-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -647,9 +647,13 @@ public final class IDNA {
StringBuffer processOut;
if(srcIsASCII == false){
// step 2: process the string
src.setIndex(saveIndex);
processOut = singleton.namePrep.prepare(src,options);
try {
// step 2: process the string
src.setIndex(saveIndex);
processOut = singleton.namePrep.prepare(src,options);
} catch (StringPrepParseException ex) {
return new StringBuffer(src.getText());
}
}else{
//just point to source
@ -664,53 +668,66 @@ public final class IDNA {
//step 3: verify ACE Prefix
if(startsWithPrefix(processOut)){
StringBuffer decodeOut = null;
//step 4: Remove the ACE Prefix
String temp = processOut.substring(ACE_PREFIX_LENGTH,processOut.length());
//step 5: Decode using punycode
StringBuffer decodeOut = Punycode.decode(new StringBuffer(temp),caseFlags);
try {
decodeOut = Punycode.decode(new StringBuffer(temp),caseFlags);
} catch (StringPrepParseException e) {
decodeOut = null;
}
//step 6:Apply toASCII
StringBuffer toASCIIOut = convertToASCII(decodeOut, options);
//step 7: verify
if(compareCaseInsensitiveASCII(processOut, toASCIIOut) !=0){
throw new StringPrepParseException("The verification step prescribed by the RFC 3491 failed",
StringPrepParseException.VERIFICATION_ERROR);
if (decodeOut != null) {
StringBuffer toASCIIOut = convertToASCII(decodeOut, options);
//step 7: verify
if(compareCaseInsensitiveASCII(processOut, toASCIIOut) !=0){
// throw new StringPrepParseException("The verification step prescribed by the RFC 3491 failed",
// StringPrepParseException.VERIFICATION_ERROR);
decodeOut = null;
}
}
//step 8: return output of step 5
return decodeOut;
if (decodeOut != null) {
return decodeOut;
}
}
}else{
// verify that STD3 ASCII rules are satisfied
if(useSTD3ASCIIRules == true){
if( srcIsLDH == false /* source contains some non-LDH characters */
|| processOut.charAt(0) == HYPHEN
|| processOut.charAt(processOut.length()-1) == HYPHEN){
if(srcIsLDH==false){
throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
StringPrepParseException.STD3_ASCII_RULES_ERROR,processOut.toString(),
(failPos>0) ? (failPos-1) : failPos);
}else if(processOut.charAt(0) == HYPHEN){
throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
StringPrepParseException.STD3_ASCII_RULES_ERROR,
processOut.toString(),0);
}else{
throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
StringPrepParseException.STD3_ASCII_RULES_ERROR,
processOut.toString(),
processOut.length());
}
}
}
// just return the source
return new StringBuffer(src.getText());
}
// }else{
// // verify that STD3 ASCII rules are satisfied
// if(useSTD3ASCIIRules == true){
// if( srcIsLDH == false /* source contains some non-LDH characters */
// || processOut.charAt(0) == HYPHEN
// || processOut.charAt(processOut.length()-1) == HYPHEN){
//
// if(srcIsLDH==false){
// throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
// StringPrepParseException.STD3_ASCII_RULES_ERROR,processOut.toString(),
// (failPos>0) ? (failPos-1) : failPos);
// }else if(processOut.charAt(0) == HYPHEN){
// throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
// StringPrepParseException.STD3_ASCII_RULES_ERROR,
// processOut.toString(),0);
//
// }else{
// throw new StringPrepParseException("The input does not conform to the STD 3 ASCII rules",
// StringPrepParseException.STD3_ASCII_RULES_ERROR,
// processOut.toString(),
// processOut.length());
//
// }
// }
// }
// // just return the source
// return new StringBuffer(src.getText());
// }
return new StringBuffer(src.getText());
}
/**

View File

@ -358,7 +358,7 @@ final class Punycode {
throw new StringPrepParseException("Illegal char found", StringPrepParseException.ILLEGAL_CHAR_FOUND);
}
digit=basicToDigit[(byte)src.charAt(in++)];
digit=basicToDigit[src.charAt(in++) & 0xFF];
if(digit<0) {
throw new StringPrepParseException("Invalid char found", StringPrepParseException.INVALID_CHAR_FOUND);
}