1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "sqlite3_android" 18 19 #include <ctype.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #ifdef SQLITE_ENABLE_ICU 25 #include <unicode/ucol.h> 26 #include <unicode/uiter.h> 27 #include <unicode/ustring.h> 28 #include <unicode/utypes.h> 29 #endif //SQLITE_ENABLE_ICU 30 #include <log/log.h> 31 32 #include "sqlite3_android.h" 33 #include "PhoneNumberUtils.h" 34 35 #define ENABLE_ANDROID_LOG 0 36 #define SMALL_BUFFER_SIZE 10 37 #define PHONE_NUMBER_BUFFER_SIZE 40 38 39 #ifdef SQLITE_ENABLE_ICU 40 static int collate16(void *p, int n1, const void *v1, int n2, const void *v2) 41 { 42 UCollator *coll = (UCollator *) p; 43 UCollationResult result = ucol_strcoll(coll, (const UChar *) v1, n1, 44 (const UChar *) v2, n2); 45 46 if (result == UCOL_LESS) { 47 return -1; 48 } else if (result == UCOL_GREATER) { 49 return 1; 50 } else { 51 return 0; 52 } 53 } 54 55 static int collate8(void *p, int n1, const void *v1, int n2, const void *v2) 56 { 57 UCollator *coll = (UCollator *) p; 58 UCharIterator i1, i2; 59 UErrorCode status = U_ZERO_ERROR; 60 61 uiter_setUTF8(&i1, (const char *) v1, n1); 62 uiter_setUTF8(&i2, (const char *) v2, n2); 63 64 UCollationResult result = ucol_strcollIter(coll, &i1, &i2, &status); 65 66 if (U_FAILURE(status)) { 67 // ALOGE("Collation iterator error: %d\n", status); 68 } 69 70 if (result == UCOL_LESS) { 71 return -1; 72 } else if (result == UCOL_GREATER) { 73 return 1; 74 } else { 75 return 0; 76 } 77 } 78 #endif // SQLITE_ENABLE_ICU 79 80 static void phone_numbers_equal(sqlite3_context * context, int argc, sqlite3_value ** argv) 81 { 82 if (argc != 2 && argc != 3) { 83 sqlite3_result_int(context, 0); 84 return; 85 } 86 87 char const * num1 = (char const *)sqlite3_value_text(argv[0]); 88 char const * num2 = (char const *)sqlite3_value_text(argv[1]); 89 90 bool use_strict = false; 91 if (argc == 3) { 92 use_strict = (sqlite3_value_int(argv[2]) != 0); 93 } 94 95 if (num1 == NULL || num2 == NULL) { 96 sqlite3_result_null(context); 97 return; 98 } 99 100 bool equal = 101 (use_strict ? 102 android::phone_number_compare_strict(num1, num2) : 103 android::phone_number_compare_loose(num1, num2)); 104 105 if (equal) { 106 sqlite3_result_int(context, 1); 107 } else { 108 sqlite3_result_int(context, 0); 109 } 110 } 111 112 static void phone_number_stripped_reversed(sqlite3_context * context, int argc, 113 sqlite3_value ** argv) 114 { 115 if (argc != 1) { 116 sqlite3_result_int(context, 0); 117 return; 118 } 119 120 char const * number = (char const *)sqlite3_value_text(argv[0]); 121 if (number == NULL) { 122 sqlite3_result_null(context); 123 return; 124 } 125 126 char out[PHONE_NUMBER_BUFFER_SIZE]; 127 int outlen = 0; 128 android::phone_number_stripped_reversed_inter(number, out, PHONE_NUMBER_BUFFER_SIZE, &outlen); 129 sqlite3_result_text(context, (const char*)out, outlen, SQLITE_TRANSIENT); 130 } 131 132 133 #if ENABLE_ANDROID_LOG 134 static void android_log(sqlite3_context * context, int argc, sqlite3_value ** argv) 135 { 136 char const * tag = "sqlite_trigger"; 137 char const * msg = ""; 138 int msgIndex = 0; 139 140 switch (argc) { 141 case 2: 142 tag = (char const *)sqlite3_value_text(argv[0]); 143 if (tag == NULL) { 144 tag = "sqlite_trigger"; 145 } 146 msgIndex = 1; 147 case 1: 148 msg = (char const *)sqlite3_value_text(argv[msgIndex]); 149 if (msg == NULL) { 150 msg = ""; 151 } 152 ALOG(LOG_INFO, tag, "%s", msg); 153 sqlite3_result_int(context, 1); 154 return; 155 156 default: 157 sqlite3_result_int(context, 0); 158 return; 159 } 160 } 161 #endif 162 163 static void delete_file(sqlite3_context * context, int argc, sqlite3_value ** argv) 164 { 165 if (argc != 1) { 166 sqlite3_result_int(context, 0); 167 return; 168 } 169 170 char const * path = (char const *)sqlite3_value_text(argv[0]); 171 // Don't allow ".." in paths 172 if (path == NULL || strstr(path, "/../") != NULL) { 173 sqlite3_result_null(context); 174 return; 175 } 176 177 // We only allow deleting files in the EXTERNAL_STORAGE path, or one of the 178 // SECONDARY_STORAGE paths 179 bool good_path = false; 180 char const * external_storage = getenv("EXTERNAL_STORAGE"); 181 if (external_storage && strncmp(external_storage, path, strlen(external_storage)) == 0) { 182 good_path = true; 183 } else { 184 // check SECONDARY_STORAGE, which should be a colon separated list of paths 185 char const * secondary_paths = getenv("SECONDARY_STORAGE"); 186 while (secondary_paths && secondary_paths[0]) { 187 const char* colon = strchr(secondary_paths, ':'); 188 int length = (colon ? colon - secondary_paths : strlen(secondary_paths)); 189 if (strncmp(secondary_paths, path, length) == 0) { 190 good_path = true; 191 } 192 secondary_paths += length; 193 while (*secondary_paths == ':') secondary_paths++; 194 } 195 } 196 197 if (!good_path) { 198 sqlite3_result_null(context); 199 return; 200 } 201 202 int err = unlink(path); 203 if (err != -1) { 204 // No error occured, return true 205 sqlite3_result_int(context, 1); 206 } else { 207 // An error occured, return false 208 sqlite3_result_int(context, 0); 209 } 210 } 211 212 #ifdef SQLITE_ENABLE_ICU 213 static void tokenize_auxdata_delete(void * data) 214 { 215 sqlite3_stmt * statement = (sqlite3_stmt *)data; 216 sqlite3_finalize(statement); 217 } 218 219 static void base16Encode(char* dest, const char* src, uint32_t size) 220 { 221 static const char * BASE16_TABLE = "0123456789abcdef"; 222 for (uint32_t i = 0; i < size; i++) { 223 char ch = *src++; 224 *dest++ = BASE16_TABLE[ (ch & 0xf0) >> 4 ]; 225 *dest++ = BASE16_TABLE[ (ch & 0x0f) ]; 226 } 227 } 228 229 struct SqliteUserData { 230 sqlite3 * handle; 231 UCollator* collator; 232 }; 233 234 /** 235 * This function is invoked as: 236 * 237 * _TOKENIZE('<token_table>', <data_row_id>, <data>, <delimiter>, 238 * <use_token_index>, <data_tag>) 239 * 240 * If <use_token_index> is omitted, it is treated as 0. 241 * If <data_tag> is omitted, it is treated as NULL. 242 * 243 * It will split <data> on each instance of <delimiter> and insert each token 244 * into <token_table>. The following columns in <token_table> are used: 245 * token TEXT, source INTEGER, token_index INTEGER, tag (any type) 246 * The token_index column is not required if <use_token_index> is 0. 247 * The tag column is not required if <data_tag> is NULL. 248 * 249 * One row is inserted for each token in <data>. 250 * In each inserted row, 'source' is <data_row_id>. 251 * In the first inserted row, 'token' is the hex collation key of 252 * the entire <data> string, and 'token_index' is 0. 253 * In each row I (where 1 <= I < N, and N is the number of tokens in <data>) 254 * 'token' will be set to the hex collation key of the I:th token (0-based). 255 * If <use_token_index> != 0, 'token_index' is set to I. 256 * If <data_tag> is not NULL, 'tag' is set to <data_tag>. 257 * 258 * In other words, there will be one row for the entire string, 259 * and one row for each token except the first one. 260 * 261 * The function returns the number of tokens generated. 262 */ 263 static void tokenize(sqlite3_context * context, int argc, sqlite3_value ** argv) 264 { 265 //ALOGD("enter tokenize"); 266 int err; 267 int useTokenIndex = 0; 268 int useDataTag = 0; 269 270 if (!(argc >= 4 || argc <= 6)) { 271 ALOGE("Tokenize requires 4 to 6 arguments"); 272 sqlite3_result_null(context); 273 return; 274 } 275 276 if (argc > 4) { 277 useTokenIndex = sqlite3_value_int(argv[4]); 278 } 279 280 if (argc > 5) { 281 useDataTag = (sqlite3_value_type(argv[5]) != SQLITE_NULL); 282 } 283 284 sqlite3 * handle = sqlite3_context_db_handle(context); 285 UCollator* collator = (UCollator*)sqlite3_user_data(context); 286 char const * tokenTable = (char const *)sqlite3_value_text(argv[0]); 287 if (tokenTable == NULL) { 288 ALOGE("tokenTable null"); 289 sqlite3_result_null(context); 290 return; 291 } 292 293 // Get or create the prepared statement for the insertions 294 sqlite3_stmt * statement = (sqlite3_stmt *)sqlite3_get_auxdata(context, 0); 295 if (!statement) { 296 char const * tokenIndexCol = useTokenIndex ? ", token_index" : ""; 297 char const * tokenIndexParam = useTokenIndex ? ", ?" : ""; 298 char const * dataTagCol = useDataTag ? ", tag" : ""; 299 char const * dataTagParam = useDataTag ? ", ?" : ""; 300 char * sql = sqlite3_mprintf("INSERT INTO %s (token, source%s%s) VALUES (?, ?%s%s);", 301 tokenTable, tokenIndexCol, dataTagCol, tokenIndexParam, dataTagParam); 302 err = sqlite3_prepare_v2(handle, sql, -1, &statement, NULL); 303 sqlite3_free(sql); 304 if (err) { 305 ALOGE("prepare failed"); 306 sqlite3_result_null(context); 307 return; 308 } 309 // This binds the statement to the table it was compiled against, which is argv[0]. 310 // If this function is ever called with a different table the finalizer will be called 311 // and sqlite3_get_auxdata() will return null above, forcing a recompile for the new table. 312 sqlite3_set_auxdata(context, 0, statement, tokenize_auxdata_delete); 313 } else { 314 // Reset the cached statement so that binding the row ID will work properly 315 sqlite3_reset(statement); 316 } 317 318 // Bind the row ID of the source row 319 int64_t rowID = sqlite3_value_int64(argv[1]); 320 err = sqlite3_bind_int64(statement, 2, rowID); 321 if (err != SQLITE_OK) { 322 ALOGE("bind failed"); 323 sqlite3_result_null(context); 324 return; 325 } 326 327 // Bind <data_tag> to the tag column 328 if (useDataTag) { 329 int dataTagParamIndex = useTokenIndex ? 4 : 3; 330 err = sqlite3_bind_value(statement, dataTagParamIndex, argv[5]); 331 if (err != SQLITE_OK) { 332 ALOGE("bind failed"); 333 sqlite3_result_null(context); 334 return; 335 } 336 } 337 338 // Get the raw bytes for the string to tokenize 339 // the string will be modified by following code 340 // however, sqlite did not reuse the string, so it is safe to not dup it 341 UChar * origData = (UChar *)sqlite3_value_text16(argv[2]); 342 if (origData == NULL) { 343 sqlite3_result_null(context); 344 return; 345 } 346 347 // Get the raw bytes for the delimiter 348 const UChar * delim = (const UChar *)sqlite3_value_text16(argv[3]); 349 if (delim == NULL) { 350 ALOGE("can't get delimiter"); 351 sqlite3_result_null(context); 352 return; 353 } 354 355 UChar * token = NULL; 356 UChar *state; 357 int numTokens = 0; 358 359 do { 360 if (numTokens == 0) { 361 token = origData; 362 } 363 364 // Reset the program so we can use it to perform the insert 365 sqlite3_reset(statement); 366 UErrorCode status = U_ZERO_ERROR; 367 char keybuf[1024]; 368 uint32_t result = ucol_getSortKey(collator, token, -1, (uint8_t*)keybuf, sizeof(keybuf)-1); 369 if (result > sizeof(keybuf)) { 370 // TODO allocate memory for this super big string 371 ALOGE("ucol_getSortKey needs bigger buffer %d", result); 372 break; 373 } 374 uint32_t keysize = result-1; 375 uint32_t base16Size = keysize*2; 376 char *base16buf = (char*)malloc(base16Size); 377 base16Encode(base16buf, keybuf, keysize); 378 err = sqlite3_bind_text(statement, 1, base16buf, base16Size, SQLITE_STATIC); 379 380 if (err != SQLITE_OK) { 381 ALOGE(" sqlite3_bind_text16 error %d", err); 382 free(base16buf); 383 break; 384 } 385 386 if (useTokenIndex) { 387 err = sqlite3_bind_int(statement, 3, numTokens); 388 if (err != SQLITE_OK) { 389 ALOGE(" sqlite3_bind_int error %d", err); 390 free(base16buf); 391 break; 392 } 393 } 394 395 err = sqlite3_step(statement); 396 free(base16buf); 397 398 if (err != SQLITE_DONE) { 399 ALOGE(" sqlite3_step error %d", err); 400 break; 401 } 402 numTokens++; 403 if (numTokens == 1) { 404 // first call 405 u_strtok_r(origData, delim, &state); 406 } 407 } while ((token = u_strtok_r(NULL, delim, &state)) != NULL); 408 sqlite3_result_int(context, numTokens); 409 } 410 411 static void localized_collator_dtor(UCollator* collator) 412 { 413 ucol_close(collator); 414 } 415 416 #define LOCALIZED_COLLATOR_NAME "LOCALIZED" 417 418 // This collator may be removed in the near future, so you MUST not use now. 419 #define PHONEBOOK_COLLATOR_NAME "PHONEBOOK" 420 421 #endif // SQLITE_ENABLE_ICU 422 423 extern "C" int register_localized_collators(sqlite3* handle __attribute((unused)), 424 const char* systemLocale __attribute((unused)), 425 int utf16Storage __attribute((unused))) 426 { 427 // This function is no-op for the VNDK, but should exist in case when some vendor 428 // module has a reference to this function. 429 #ifdef SQLITE_ENABLE_ICU 430 UErrorCode status = U_ZERO_ERROR; 431 UCollator* collator = ucol_open(systemLocale, &status); 432 if (U_FAILURE(status)) { 433 return -1; 434 } 435 436 ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); 437 if (U_FAILURE(status)) { 438 return -1; 439 } 440 441 int err; 442 if (utf16Storage) { 443 err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF16, collator, 444 collate16, (void(*)(void*))localized_collator_dtor); 445 } else { 446 err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF8, collator, 447 collate8, (void(*)(void*))localized_collator_dtor); 448 } 449 450 if (err != SQLITE_OK) { 451 return err; 452 } 453 454 // Register the _TOKENIZE function 455 err = sqlite3_create_function(handle, "_TOKENIZE", 4, SQLITE_UTF16, collator, tokenize, NULL, NULL); 456 if (err != SQLITE_OK) { 457 return err; 458 } 459 err = sqlite3_create_function(handle, "_TOKENIZE", 5, SQLITE_UTF16, collator, tokenize, NULL, NULL); 460 if (err != SQLITE_OK) { 461 return err; 462 } 463 err = sqlite3_create_function(handle, "_TOKENIZE", 6, SQLITE_UTF16, collator, tokenize, NULL, NULL); 464 if (err != SQLITE_OK) { 465 return err; 466 } 467 468 //// PHONEBOOK_COLLATOR 469 status = U_ZERO_ERROR; 470 collator = ucol_open(systemLocale, &status); 471 if (U_FAILURE(status)) { 472 return -1; 473 } 474 475 status = U_ZERO_ERROR; 476 ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); 477 if (U_FAILURE(status)) { 478 return -1; 479 } 480 481 if (utf16Storage) { 482 err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF16, collator, 483 collate16, (void(*)(void*))localized_collator_dtor); 484 } else { 485 err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF8, collator, 486 collate8, (void(*)(void*))localized_collator_dtor); 487 } 488 489 if (err != SQLITE_OK) { 490 return err; 491 } 492 //// PHONEBOOK_COLLATOR 493 #endif //SQLITE_ENABLE_ICU 494 495 return SQLITE_OK; 496 } 497 498 499 extern "C" int register_android_functions(sqlite3 * handle, int utf16Storage __attribute((unused))) 500 { 501 int err; 502 #ifdef SQLITE_ENABLE_ICU 503 UErrorCode status = U_ZERO_ERROR; 504 505 UCollator * collator = ucol_open(NULL, &status); 506 if (U_FAILURE(status)) { 507 return -1; 508 } 509 510 if (utf16Storage) { 511 // Note that text should be stored as UTF-16 512 err = sqlite3_exec(handle, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); 513 if (err != SQLITE_OK) { 514 return err; 515 } 516 517 // Register the UNICODE collation 518 err = sqlite3_create_collation_v2(handle, "UNICODE", SQLITE_UTF16, collator, collate16, 519 (void(*)(void*))localized_collator_dtor); 520 } else { 521 err = sqlite3_create_collation_v2(handle, "UNICODE", SQLITE_UTF8, collator, collate8, 522 (void(*)(void*))localized_collator_dtor); 523 } 524 525 if (err != SQLITE_OK) { 526 return err; 527 } 528 #endif // SQLITE_ENABLE_ICU 529 530 // Register the PHONE_NUM_EQUALS function 531 err = sqlite3_create_function( 532 handle, "PHONE_NUMBERS_EQUAL", 2, 533 SQLITE_UTF8, NULL, phone_numbers_equal, NULL, NULL); 534 if (err != SQLITE_OK) { 535 return err; 536 } 537 538 // Register the PHONE_NUM_EQUALS function with an additional argument "use_strict" 539 err = sqlite3_create_function( 540 handle, "PHONE_NUMBERS_EQUAL", 3, 541 SQLITE_UTF8, NULL, phone_numbers_equal, NULL, NULL); 542 if (err != SQLITE_OK) { 543 return err; 544 } 545 546 // Register the _DELETE_FILE function 547 err = sqlite3_create_function(handle, "_DELETE_FILE", 1, SQLITE_UTF8, NULL, delete_file, NULL, NULL); 548 if (err != SQLITE_OK) { 549 return err; 550 } 551 552 #if ENABLE_ANDROID_LOG 553 // Register the _LOG function 554 err = sqlite3_create_function(handle, "_LOG", 1, SQLITE_UTF8, NULL, android_log, NULL, NULL); 555 if (err != SQLITE_OK) { 556 return err; 557 } 558 #endif 559 560 // Register the _PHONE_NUMBER_STRIPPED_REVERSED function, which imitates 561 // PhoneNumberUtils.getStrippedReversed. This function is used by 562 // packages/providers/ContactsProvider/src/com/android/providers/contacts/LegacyApiSupport.java 563 // to provide compatibility with Android 1.6 and earlier. 564 err = sqlite3_create_function(handle, 565 "_PHONE_NUMBER_STRIPPED_REVERSED", 566 1, SQLITE_UTF8, NULL, 567 phone_number_stripped_reversed, 568 NULL, NULL); 569 if (err != SQLITE_OK) { 570 return err; 571 } 572 573 return SQLITE_OK; 574 } 575