]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the ICU extension LIKE function so that it does not read past the end of a buffer...
authordan <dan@noemail.net>
Fri, 26 Feb 2016 16:03:29 +0000 (16:03 +0000)
committerdan <dan@noemail.net>
Fri, 26 Feb 2016 16:03:29 +0000 (16:03 +0000)
FossilOrigin-Name: 424b7aee3310b9782bd312589dc3d9f287aa04b8

ext/icu/icu.c
manifest
manifest.uuid

index a2ff49274ceaefe6600691432518d0a459fe3eea..56543667ca1dbf95de4dbeb68ce9960c4ecc0401 100644 (file)
@@ -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;
 }
 
 /*
index b196f4d2fb1bf7ed17fa5e900ba911aa72cd5c75..046a24e640e19c9a4e59ff67c58034e09eee67cb 100644 (file)
--- 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
index dcf6861a1e151e45d4cf44fbe7740522c551283f..b891f1a56123e3fd07206cf8a0aa854eb5866026 100644 (file)
@@ -1 +1 @@
-374b5108087a2eae03676c0f3469b37a272145bf
\ No newline at end of file
+424b7aee3310b9782bd312589dc3d9f287aa04b8
\ No newline at end of file