From: dan Date: Fri, 26 Feb 2016 16:03:29 +0000 (+0000) Subject: Fix the ICU extension LIKE function so that it does not read past the end of a buffer... X-Git-Tag: version-3.12.0~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=38c3d3d8a5369a03ed4d796acd7df3d369f2a9b8;p=thirdparty%2Fsqlite.git Fix the ICU extension LIKE function so that it does not read past the end of a buffer if it it passed malformed utf-8. FossilOrigin-Name: 424b7aee3310b9782bd312589dc3d9f287aa04b8 --- diff --git a/ext/icu/icu.c b/ext/icu/icu.c index a2ff49274c..56543667ca 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -60,6 +60,38 @@ static void xFree(void *p){ sqlite3_free(p); } +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. It is copied here from SQLite source +** code file utf8.c. +*/ +static const unsigned char icuUtf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define SQLITE_ICU_READ_UTF8(zIn, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = icuUtf8Trans1[c-0xc0]; \ + while( (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + } + +#define SQLITE_ICU_SKIP_UTF8(zIn) \ + assert( *zIn ); \ + if( *(zIn++)>=0xc0 ){ \ + while( (*zIn & 0xc0)==0x80 ){zIn++;} \ + } + + /* ** Compare two UTF-8 strings for equality where the first string is ** a "LIKE" expression. Return true (1) if they are the same and @@ -73,16 +105,14 @@ static int icuLikeCompare( static const int MATCH_ONE = (UChar32)'_'; static const int MATCH_ALL = (UChar32)'%'; - int iPattern = 0; /* Current byte index in zPattern */ - int iString = 0; /* Current byte index in zString */ - int prevEscape = 0; /* True if the previous character was uEsc */ - while( zPattern[iPattern]!=0 ){ + while( 1 ){ /* Read (and consume) the next character from the input pattern. */ UChar32 uPattern; - U8_NEXT_UNSAFE(zPattern, iPattern, uPattern); + SQLITE_ICU_READ_UTF8(zPattern, uPattern); + if( uPattern==0 ) break; /* There are now 4 possibilities: ** @@ -99,28 +129,28 @@ static int icuLikeCompare( ** MATCH_ALL. For each MATCH_ONE, skip one character in the ** test string. */ - while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){ + while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){ if( c==MATCH_ONE ){ - if( zString[iString]==0 ) return 0; - U8_FWD_1_UNSAFE(zString, iString); + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); } - iPattern++; + zPattern++; } - if( zPattern[iPattern]==0 ) return 1; + if( *zPattern==0 ) return 1; - while( zString[iString] ){ - if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){ + while( *zString ){ + if( icuLikeCompare(zPattern, zString, uEsc) ){ return 1; } - U8_FWD_1_UNSAFE(zString, iString); + SQLITE_ICU_SKIP_UTF8(zString); } return 0; }else if( !prevEscape && uPattern==MATCH_ONE ){ /* Case 2. */ - if( zString[iString]==0 ) return 0; - U8_FWD_1_UNSAFE(zString, iString); + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); }else if( !prevEscape && uPattern==uEsc){ /* Case 3. */ @@ -129,7 +159,7 @@ static int icuLikeCompare( }else{ /* Case 4. */ UChar32 uString; - U8_NEXT_UNSAFE(zString, iString, uString); + SQLITE_ICU_READ_UTF8(zString, uString); uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); if( uString!=uPattern ){ @@ -139,7 +169,7 @@ static int icuLikeCompare( } } - return zString[iString]==0; + return *zString==0; } /* diff --git a/manifest b/manifest index b196f4d2fb..046a24e640 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sthe\snew\sSQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER\soption\sto\s\nsqlite3_db_config()\sthat\scan\sbe\sused\sto\sactivate\sthe\stwo-argument\sversion\nof\sfts3_tokenizer()\sfor\sa\sspecific\sdatabase\sconnection\sat\srun-time. -D 2016-02-26T15:38:24.549 +C Fix\sthe\sICU\sextension\sLIKE\sfunction\sso\sthat\sit\sdoes\snot\sread\spast\sthe\send\sof\sa\sbuffer\sif\sit\sit\spassed\smalformed\sutf-8. +D 2016-02-26T16:03:29.500 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 28fc4ee02333996d31b3602b39eeb8e609a89ce4 @@ -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 b2732aef0b076e4276d9b39b5a33cec7a05e1413 +F ext/icu/icu.c 194e972ff3545084b56c459131eb80e1485da75e F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 @@ -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 ff3d7f845e1875d6729f64f5231db1c376892f31 -R 31d803939428fd2d10225002a384e77a -U drh -Z 2070e36304d2e6c69aaa4c28fc3295af +P 374b5108087a2eae03676c0f3469b37a272145bf +R 1de55b3a8f2d3749e97e04af07972bbe +U dan +Z 5dfcb2d8f6d42b01529359e44d97d92b diff --git a/manifest.uuid b/manifest.uuid index dcf6861a1e..b891f1a561 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -374b5108087a2eae03676c0f3469b37a272145bf \ No newline at end of file +424b7aee3310b9782bd312589dc3d9f287aa04b8 \ No newline at end of file