diff --git a/icu4c/source/common/ustr_wcs.c b/icu4c/source/common/ustr_wcs.c index 3b0e4b08452..9de5e223155 100644 --- a/icu4c/source/common/ustr_wcs.c +++ b/icu4c/source/common/ustr_wcs.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2001-2006, International Business Machines +* Copyright (C) 2001-2010, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -232,7 +232,9 @@ u_strToWCS(wchar_t *dest, return NULL; } - if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) + ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } @@ -484,8 +486,10 @@ u_strFromWCS(UChar *dest, if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ return NULL; } - - if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ + + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) + ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } diff --git a/icu4c/source/common/ustrtrns.c b/icu4c/source/common/ustrtrns.c index 6de65219259..bae52675f35 100644 --- a/icu4c/source/common/ustrtrns.c +++ b/icu4c/source/common/ustrtrns.c @@ -49,7 +49,8 @@ u_strFromUTF32WithSub(UChar *dest, if(U_FAILURE(*pErrorCode)){ return NULL; } - if( (src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0) || + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) || subchar > 0x10ffff || U_IS_SURROGATE(subchar) ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; @@ -163,7 +164,8 @@ u_strToUTF32WithSub(UChar32 *dest, if(U_FAILURE(*pErrorCode)){ return NULL; } - if( (src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0) || + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) || subchar > 0x10ffff || U_IS_SURROGATE(subchar) ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; @@ -409,7 +411,8 @@ u_strFromUTF8WithSub(UChar *dest, return NULL; } - if( (src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0) || + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) || subchar > 0x10ffff || U_IS_SURROGATE(subchar) ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; @@ -742,7 +745,9 @@ u_strFromUTF8Lenient(UChar *dest, return NULL; } - if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)) { + if( (src==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) + ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } @@ -981,7 +986,8 @@ u_strToUTF8WithSub(char *dest, return NULL; } - if( (pSrc==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0) || + if( (pSrc==NULL && srcLength!=0) || srcLength < -1 || + (destCapacity<0) || (dest == NULL && destCapacity > 0) || subchar > 0x10ffff || U_IS_SURROGATE(subchar) ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; diff --git a/icu4c/source/test/cintltst/custrtrn.c b/icu4c/source/test/cintltst/custrtrn.c index 76324cdb4ea..5397ff27a89 100644 --- a/icu4c/source/test/cintltst/custrtrn.c +++ b/icu4c/source/test/cintltst/custrtrn.c @@ -43,6 +43,7 @@ static void Test_widestrs(void); static void Test_WCHART_LongString(void); static void Test_strToJavaModifiedUTF8(void); static void Test_strFromJavaModifiedUTF8(void); +static void TestNullEmptySource(void); void addUCharTransformTest(TestNode** root) @@ -61,6 +62,7 @@ addUCharTransformTest(TestNode** root) #endif addTest(root, &Test_strToJavaModifiedUTF8, "custrtrn/Test_strToJavaModifiedUTF8"); addTest(root, &Test_strFromJavaModifiedUTF8, "custrtrn/Test_strFromJavaModifiedUTF8"); + addTest(root, &TestNullEmptySource, "custrtrn/TestNullEmptySource"); } static const UChar32 src32[]={ @@ -1176,16 +1178,16 @@ static void Test_UChar_WCHART_API(void){ log_err("u_strToWCS() should return NULL with a bad argument\n"); } - /* Bad UErrorCode arguments. */ + /* NULL source & destination. */ err = U_ZERO_ERROR; u_strFromWCS(NULL,0,NULL,NULL,0,&err); - if (err != U_ILLEGAL_ARGUMENT_ERROR) { - log_err("u_strFromWCS() didn't fail as expected with bad arguments. Error: %s \n", u_errorName(err)); + if (err != U_STRING_NOT_TERMINATED_WARNING) { + log_err("u_strFromWCS(NULL, NULL) failed. Error: %s \n", u_errorName(err)); } err = U_ZERO_ERROR; u_strToWCS(NULL,0,NULL,NULL,0,&err); - if (err != U_ILLEGAL_ARGUMENT_ERROR) { - log_err("u_strToWCS() didn't fail as expected with bad arguments. Error: %s \n", u_errorName(err)); + if (err != U_STRING_NOT_TERMINATED_WARNING) { + log_err("u_strToWCS(NULL, NULL) failed. Error: %s \n", u_errorName(err)); } err = U_ZERO_ERROR; @@ -1955,3 +1957,128 @@ static void Test_strFromJavaModifiedUTF8() { log_err("u_strFromJavaModifiedUTF8WithSub(subchar is surrogate) failed - %s\n", u_errorName(errorCode)); } } + +/* test that string transformation functions permit NULL source pointer when source length==0 */ +static void TestNullEmptySource() { + char dest8[4]={ 3, 3, 3, 3 }; + UChar dest16[4]={ 3, 3, 3, 3 }; + UChar32 dest32[4]={ 3, 3, 3, 3 }; +#if (defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32)) || (!UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION) + wchar_t destW[4]={ 3, 3, 3, 3 }; +#endif + + int32_t length; + UErrorCode errorCode; + + /* u_strFromXyz() */ + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromUTF8(dest16, LENGTHOF(dest16), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromUTF8(source=NULL, sourceLength=0) failed\n"); + } + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromUTF8WithSub(dest16, LENGTHOF(dest16), &length, NULL, 0, 0xfffd, NULL, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromUTF8WithSub(source=NULL, sourceLength=0) failed\n"); + } + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromUTF8Lenient(dest16, LENGTHOF(dest16), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromUTF8Lenient(source=NULL, sourceLength=0) failed\n"); + } + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromUTF32(dest16, LENGTHOF(dest16), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromUTF32(source=NULL, sourceLength=0) failed\n"); + } + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromUTF32WithSub(dest16, LENGTHOF(dest16), &length, NULL, 0, 0xfffd, NULL, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromUTF32WithSub(source=NULL, sourceLength=0) failed\n"); + } + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromJavaModifiedUTF8WithSub(dest16, LENGTHOF(dest16), &length, NULL, 0, 0xfffd, NULL, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromJavaModifiedUTF8WithSub(source=NULL, sourceLength=0) failed\n"); + } + + /* u_strToXyz() */ + + dest8[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToUTF8(dest8, LENGTHOF(dest8), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest8[0]!=0 || dest8[1]!=3) { + log_err("u_strToUTF8(source=NULL, sourceLength=0) failed\n"); + } + + dest8[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToUTF8WithSub(dest8, LENGTHOF(dest8), &length, NULL, 0, 0xfffd, NULL, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest8[0]!=0 || dest8[1]!=3) { + log_err("u_strToUTF8(source=NULL, sourceLength=0) failed\n"); + } + + dest32[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToUTF32(dest32, LENGTHOF(dest32), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest32[0]!=0 || dest32[1]!=3) { + log_err("u_strToUTF32(source=NULL, sourceLength=0) failed\n"); + } + + dest32[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToUTF32WithSub(dest32, LENGTHOF(dest32), &length, NULL, 0, 0xfffd, NULL, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest32[0]!=0 || dest32[1]!=3) { + log_err("u_strToUTF32WithSub(source=NULL, sourceLength=0) failed\n"); + } + + dest8[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToJavaModifiedUTF8(dest8, LENGTHOF(dest8), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest8[0]!=0 || dest8[1]!=3) { + log_err("u_strToJavaModifiedUTF8(source=NULL, sourceLength=0) failed\n"); + } + +#if (defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32)) || (!UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION) + + dest16[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strFromWCS(dest16, LENGTHOF(dest16), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || dest16[0]!=0 || dest16[1]!=3) { + log_err("u_strFromWCS(source=NULL, sourceLength=0) failed\n"); + } + + destW[0]=3; + length=3; + errorCode=U_ZERO_ERROR; + u_strToWCS(destW, LENGTHOF(destW), &length, NULL, 0, &errorCode); + if(errorCode!=U_ZERO_ERROR || length!=0 || destW[0]!=0 || destW[1]!=3) { + log_err("u_strToWCS(source=NULL, sourceLength=0) failed\n"); + } + +#endif +}