ICU-5510 Add argument checks to verify that complete UChar * buffers are being used.

X-SVN-Rev: 20654
This commit is contained in:
George Rhoten 2006-11-14 22:59:46 +00:00
parent fc18b5c750
commit e2be25e646
2 changed files with 81 additions and 17 deletions

View file

@ -1116,13 +1116,13 @@ ucnv_fromUnicode(UConverter *cnv,
s=*source;
t=*target;
if(sourceLimit<s || targetLimit<t) {
*err=U_ILLEGAL_ARGUMENT_ERROR;
return;
}
/*
* Make sure that the buffer sizes do not exceed the number range for
* All these conditions should never happen.
*
* 1) Make sure that the limits are >= 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<s || targetLimit<t ||
((size_t)(sourceLimit-s)>(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<s || targetLimit<t) {
*err=U_ILLEGAL_ARGUMENT_ERROR;
return;
}
/*
* Make sure that the buffer sizes do not exceed the number range for
* All these conditions should never happen.
*
* 1) Make sure that the limits are >= 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<s || targetLimit<t ||
((size_t)(sourceLimit-s)>(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;

View file

@ -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);
}