From 88a1650859cd828a80261f4c228247fef5635790 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Feb 2016 21:20:57 +0000 Subject: [PATCH] Fix a potential buffer overflow in the ICU upper() function. FossilOrigin-Name: b8dc1b9f5d413000387bfe784b69f5d0ee5c0489 --- ext/icu/icu.c | 48 ++++++++++++++++++++++++++++-------------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/icu.test | 9 +++++++++ 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 56543667ca..263cd98275 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -355,11 +355,11 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; - UChar *zOutput; + UChar *zOutput = 0; int nInput; - int nOutput; - - UErrorCode status = U_ZERO_ERROR; + int nOut; + int cnt; + UErrorCode status; const char *zLocale = 0; assert(nArg==1 || nArg==2); @@ -371,26 +371,34 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ if( !zInput ){ return; } - nInput = sqlite3_value_bytes16(apArg[0]); - - nOutput = nInput * 2 + 2; - zOutput = sqlite3_malloc(nOutput); - if( !zOutput ){ + nOut = nInput = sqlite3_value_bytes16(apArg[0]); + if( nOut==0 ){ + sqlite3_result_text16(p, "", 0, SQLITE_STATIC); return; } - if( sqlite3_user_data(p) ){ - u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); - }else{ - u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); - } - - if( !U_SUCCESS(status) ){ - icuFunctionError(p, "u_strToLower()/u_strToUpper", status); - return; + for(cnt=0; cnt<2; cnt++){ + UChar *zNew = sqlite3_realloc(zOutput, nOut); + if( zNew==0 ){ + sqlite3_free(zOutput); + sqlite3_result_error_nomem(p); + return; + } + zOutput = zNew; + status = U_ZERO_ERROR; + if( sqlite3_user_data(p) ){ + nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + }else{ + nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + } + if( !U_SUCCESS(status) ){ + if( status==U_BUFFER_OVERFLOW_ERROR ) continue; + icuFunctionError(p, + sqlite3_user_data(p) ? "u_strToUpper()" : "u_strToLower", status); + return; + } } - - sqlite3_result_text16(p, zOutput, -1, xFree); + sqlite3_result_text16(p, zOutput, nOut, xFree); } /* diff --git a/manifest b/manifest index 3b14fffa3a..6f2f8535ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefinements\sto\sthe\sMSVC\sbatch\sbuild\sprocess. -D 2016-02-26T21:03:16.418 +C Fix\sa\spotential\sbuffer\soverflow\sin\sthe\sICU\supper()\sfunction. +D 2016-02-26T21:20:57.225 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 56ea123a975690bf9ed38b31bb89ff87b02a7c2b @@ -198,7 +198,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 194e972ff3545084b56c459131eb80e1485da75e +F ext/icu/icu.c be1f90d8babafe6d1a55a6912161bcac75baee0e F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 @@ -777,7 +777,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f -F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 +F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176 @@ -1450,7 +1450,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 424b7aee3310b9782bd312589dc3d9f287aa04b8 4e54e9c0fefe417f94a2d95921acf61b1dda5ca4 -R 7da9769ad29c99be35565d7e5f8b1154 -U mistachkin -Z 7d4c099032b4aee5af44d708663be688 +P cf4e4fbdb6a29b7fbd5150958ab4f8f2a1cd7f21 +R a5aa0b45f5ae16ce5e364c4bc7498593 +U drh +Z d4cfa74b26d8bc26b2ff43ad0d4d53e2 diff --git a/manifest.uuid b/manifest.uuid index 07b70ce13e..38c7afbca2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf4e4fbdb6a29b7fbd5150958ab4f8f2a1cd7f21 \ No newline at end of file +b8dc1b9f5d413000387bfe784b69f5d0ee5c0489 \ No newline at end of file diff --git a/test/icu.test b/test/icu.test index 73cb9b913e..743bcfaea1 100644 --- a/test/icu.test +++ b/test/icu.test @@ -72,6 +72,10 @@ test_expr icu-2.6 {i1=$::OGRAVE} {upper(i1)} $::OGRAVE test_expr icu-2.7 {i1=$::szlig} {upper(i1)} "SS" test_expr icu-2.8 {i1='SS'} {lower(i1)} "ss" +do_execsql_test icu-2.9 { + SELECT upper(char(0xfb04,0xfb04,0xfb04,0xfb04)); +} {FFLFFLFFLFFL} + # In turkish (locale="tr_TR"), the lower case version of I # is "small dotless i" (code point 0x131 (decimal 305)). # @@ -133,4 +137,9 @@ do_catchsql_test icu-5.4 { do_catchsql_test icu-5.4 { SELECT 'abc' REGEXP } {1 {near " ": syntax error}} do_catchsql_test icu-5.5 { SELECT 'abc' REGEXP, 1 } {1 {near ",": syntax error}} + +do_malloc_test icu-6.10 -sqlbody { + SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04)); +} + finish_test -- 2.47.2