From e2be25e6467387e7d4958c5eeaa7d5e3eca96cc7 Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Tue, 14 Nov 2006 22:59:46 +0000 Subject: [PATCH] ICU-5510 Add argument checks to verify that complete UChar * buffers are being used. X-SVN-Rev: 20654 --- icu4c/source/common/ucnv.c | 38 ++++++++++------- icu4c/source/test/cintltst/ccapitst.c | 60 ++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/icu4c/source/common/ucnv.c b/icu4c/source/common/ucnv.c index ff6eebafd1a..23928537351 100644 --- a/icu4c/source/common/ucnv.c +++ b/icu4c/source/common/ucnv.c @@ -1116,13 +1116,13 @@ ucnv_fromUnicode(UConverter *cnv, s=*source; t=*target; - if(sourceLimit= to the address source or target + * + * 2) Make sure that the buffer sizes do not exceed the number range for * int32_t because some functions use the size (in units or bytes) * rather than comparing pointers, and because offsets are int32_t values. * @@ -1132,11 +1132,15 @@ ucnv_fromUnicode(UConverter *cnv, * not be able to maintain the semantics that either the source must be * consumed or the target filled (unless an error occurs). * An adjustment would be targetLimit=t+0x7fffffff; for example. + * + * 3) Make sure that the user didn't incorrectly cast a UChar * pointer + * to a char * pointer and provide an incomplete UChar code unit. */ - if( + if (sourceLimit(size_t)0x3fffffff && sourceLimit>s) || - ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) - ) { + ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) || + (((const char *)sourceLimit-(const char *)s) & 1) != 0) + { *err=U_ILLEGAL_ARGUMENT_ERROR; return; } @@ -1514,13 +1518,13 @@ ucnv_toUnicode(UConverter *cnv, s=*source; t=*target; - if(sourceLimit= to the address source or target + * + * 2) Make sure that the buffer sizes do not exceed the number range for * int32_t because some functions use the size (in units or bytes) * rather than comparing pointers, and because offsets are int32_t values. * @@ -1530,10 +1534,14 @@ ucnv_toUnicode(UConverter *cnv, * not be able to maintain the semantics that either the source must be * consumed or the target filled (unless an error occurs). * An adjustment would be sourceLimit=t+0x7fffffff; for example. + * + * 3) Make sure that the user didn't incorrectly cast a UChar * pointer + * to a char * pointer and provide an incomplete UChar code unit. */ - if( + if (sourceLimit(size_t)0x7fffffff && sourceLimit>s) || - ((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t) + ((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t) || + (((const char *)targetLimit-(const char *)t) & 1) != 0 ) { *err=U_ILLEGAL_ARGUMENT_ERROR; return; diff --git a/icu4c/source/test/cintltst/ccapitst.c b/icu4c/source/test/cintltst/ccapitst.c index 3c55396bd6f..4a300faec14 100644 --- a/icu4c/source/test/cintltst/ccapitst.c +++ b/icu4c/source/test/cintltst/ccapitst.c @@ -115,6 +115,7 @@ static void TestFromUCountPending(void); static void TestDefaultName(void); static void TestCompareNames(void); static void TestSubstString(void); +static void InvalidArguments(void); void addTestConvert(TestNode** root); @@ -126,11 +127,9 @@ void addTestConvert(TestNode** root) addTest(root, &TestAlias, "tsconv/ccapitst/TestAlias"); addTest(root, &TestDuplicateAlias, "tsconv/ccapitst/TestDuplicateAlias"); addTest(root, &TestConvertSafeClone, "tsconv/ccapitst/TestConvertSafeClone"); - #if !UCONFIG_NO_LEGACY_CONVERSION addTest(root, &TestConvertSafeCloneCallback,"tsconv/ccapitst/TestConvertSafeCloneCallback"); #endif - addTest(root, &TestCCSID, "tsconv/ccapitst/TestCCSID"); addTest(root, &TestJ932, "tsconv/ccapitst/TestJ932"); addTest(root, &TestJ1968, "tsconv/ccapitst/TestJ1968"); @@ -144,6 +143,7 @@ void addTestConvert(TestNode** root) addTest(root, &TestDefaultName, "tsconv/ccapitst/TestDefaultName"); addTest(root, &TestCompareNames, "tsconv/ccapitst/TestCompareNames"); addTest(root, &TestSubstString, "tsconv/ccapitst/TestSubstString"); + addTest(root, &InvalidArguments, "tsconv/ccapitst/InvalidArguments"); } static void ListNames(void) { @@ -3246,3 +3246,59 @@ TestSubstString() { * functions with UErrorCode parameters. */ } + +static void +InvalidArguments() { + UConverter *cnv; + UErrorCode errorCode; + char charBuffer[2] = {1, 1}; + char ucharAsCharBuffer[2] = {2, 2}; + char *charsPtr = charBuffer; + UChar *ucharsPtr = (UChar *)ucharAsCharBuffer; + UChar *ucharsBadPtr = (UChar *)(ucharAsCharBuffer + 1); + + errorCode=U_ZERO_ERROR; + cnv=ucnv_open("UTF-8", &errorCode); + if(U_FAILURE(errorCode)) { + log_err("ucnv_open() failed - %s\n", u_errorName(errorCode)); + return; + } + + errorCode=U_ZERO_ERROR; + /* This one should fail because an incomplete UChar is being passed in */ + ucnv_fromUnicode(cnv, &charsPtr, charsPtr, &ucharsPtr, ucharsBadPtr, NULL, TRUE, &errorCode); + if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) { + log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode)); + } + + errorCode=U_ZERO_ERROR; + /* This one should fail because ucharsBadPtr is > than ucharsPtr */ + ucnv_fromUnicode(cnv, &charsPtr, charsPtr, &ucharsBadPtr, ucharsPtr, NULL, TRUE, &errorCode); + if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) { + log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode)); + } + + errorCode=U_ZERO_ERROR; + /* This one should fail because an incomplete UChar is being passed in */ + ucnv_toUnicode(cnv, &ucharsPtr, ucharsBadPtr, &charsPtr, charsPtr, NULL, TRUE, &errorCode); + if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) { + log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode)); + } + + errorCode=U_ZERO_ERROR; + /* This one should fail because ucharsBadPtr is > than ucharsPtr */ + ucnv_toUnicode(cnv, &ucharsBadPtr, ucharsPtr, &charsPtr, charsPtr, NULL, TRUE, &errorCode); + if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) { + log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode)); + } + + if (charBuffer[0] != 1 || charBuffer[1] != 1 + || ucharAsCharBuffer[0] != 2 || ucharAsCharBuffer[1] != 2) + { + log_err("Data was incorrectly written to buffers\n"); + } + + ucnv_close(cnv); +} + +