| # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//testing/libfuzzer/fuzzer_test.gni") |
| |
| declare_args() { |
| # Controls whether the build should uses the version of sqlite3 library |
| # shipped with the system (currently only supported on iOS) or the one |
| # shipped with Chromium source. |
| use_system_sqlite = is_ios |
| } |
| |
| if (!use_system_sqlite) { |
| config("sqlite_warnings") { |
| cflags = [] |
| if (is_clang) { |
| # sqlite contains a few functions that are unused, at least on |
| # Windows with Chromium's sqlite patches applied |
| # (interiorCursorEOF fts3EvalDeferredPhrase |
| # fts3EvalSelectDeferred sqlite3Fts3InitHashTable |
| # sqlite3Fts3InitTok). |
| cflags += [ "-Wno-unused-function" ] |
| } |
| if (is_linux) { |
| cflags += [ |
| # SQLite doesn"t believe in compiler warnings, |
| # preferring testing. |
| # http://www.sqlite.org/faq.html#q17 |
| "-Wno-int-to-pointer-cast", |
| "-Wno-pointer-to-int-cast", |
| ] |
| } |
| } |
| |
| # "sqlite3" can cause conflicts with the system library. |
| component("chromium_sqlite3") { |
| visibility = [ ":*" ] |
| sources = [ |
| "amalgamation/config.h", |
| "amalgamation/sqlite3.c", |
| "amalgamation/sqlite3.h", |
| "src/src/recover.c", |
| "src/src/recover.h", |
| "src/src/recover_varint.c", |
| ] |
| |
| cflags = [] |
| defines = [ |
| "SQLITE_ENABLE_FTS3", |
| |
| # New unicode61 tokenizer with built-in tables. |
| "SQLITE_DISABLE_FTS3_UNICODE", |
| |
| # Chromium currently does not enable fts4, disable extra code. |
| "SQLITE_DISABLE_FTS4_DEFERRED", |
| "SQLITE_ENABLE_ICU", |
| "SQLITE_ENABLE_MEMORY_MANAGEMENT", |
| "SQLITE_SECURE_DELETE", |
| |
| # Custom flag to tweak pcache pools. |
| # TODO(shess): This shouldn't use faux-SQLite naming. |
| "SQLITE_SEPARATE_CACHE_POOLS", |
| |
| # TODO(shess): SQLite adds mutexes to protect structures which cross |
| # threads. In theory Chromium should be able to turn this to "2" which |
| # should give a slight speed boost. "2" is safe as long as a single |
| # connection is not used by more than one thread at a time. |
| "SQLITE_THREADSAFE=1", |
| |
| # SQLite can spawn threads to sort in parallel if configured |
| # appropriately. Chromium doesn't configure SQLite for that, and would |
| # prefer to control distribution to worker threads. |
| "SQLITE_MAX_WORKER_THREADS=0", |
| |
| # Allow 256MB mmap footprint per connection. Should not be too open-ended |
| # as that could cause memory fragmentation. 50MB encompasses the 99th |
| # percentile of Chrome databases in the wild. |
| # TODO(shess): A 64-bit-specific value could be 1G or more. |
| # TODO(shess): Figure out if exceeding this is costly. |
| "SQLITE_MAX_MMAP_SIZE=268435456", |
| |
| # Use a read-only memory map when mmap'ed I/O is enabled to prevent memory |
| # stompers from directly corrupting the database. |
| # TODO(shess): Upstream the ability to use this define. |
| "SQLITE_MMAP_READ_ONLY=1", |
| |
| # By default SQLite pre-allocates 100 pages of pcache data, which will not |
| # be released until the handle is closed. This is contrary to Chromium's |
| # memory-usage goals. |
| "SQLITE_DEFAULT_PCACHE_INITSZ=0", |
| |
| # NOTE(shess): Some defines can affect the amalgamation. Those should be |
| # added to google_generate_amalgamation.sh, and the amalgamation |
| # re-generated. Usually this involves disabling features which include |
| # keywords or syntax, for instance SQLITE_OMIT_VIRTUALTABLE omits the |
| # virtual table syntax entirely. Missing an item usually results in |
| # syntax working but execution failing. Review: |
| # src/src/parse.py |
| # src/tool/mkkeywordhash.c |
| ] |
| if (is_component_build) { |
| if (is_win) { |
| defines += [ "SQLITE_API=__declspec(dllexport)" ] |
| } else { |
| defines += [ "SQLITE_API=__attribute__((visibility(\"default\")))" ] |
| } |
| } |
| if (is_posix) { |
| defines += [ |
| # Allow xSleep() call on Unix to use usleep() rather than sleep(), so it |
| # will have microsecond precision. Should only affect contended |
| # databases via the busy callback. Browser profile databases are mostly |
| # exclusive, but renderer databases may allow for contention. |
| "HAVE_USLEEP=1", |
| |
| # Use pread/pwrite directly rather than emulating them. |
| "USE_PREAD=1", |
| ] |
| } |
| if (is_linux || is_android) { |
| defines += [ |
| # Linux provides fdatasync(), a faster equivalent of fsync(). |
| "fdatasync=fdatasync", |
| ] |
| } |
| |
| # Pull in config.h on Linux. This allows use of preprocessor macros which |
| # are not available to the build config. |
| if (is_linux) { |
| defines += [ "_HAVE_SQLITE_CONFIG_H" ] |
| } |
| |
| if (using_sanitizer) { |
| # Limit max length of data blobs and queries for fuzzing builds by 128 MB. |
| defines += [ |
| "SQLITE_MAX_LENGTH=128000000", |
| "SQLITE_MAX_SQL_LENGTH=128000000", |
| "SQLITE_PRINTF_PRECISION_LIMIT=1280000", |
| ] |
| |
| # During fuzz testing, valid SQL queries generated by fuzzing engine may |
| # lead to large memory allocations. If that happens, fuzzer reports an |
| # out-of-memory error. However, such errors are not valid bugs. |
| # To avoid hitting those irrelevant OOMs, we limit max number of memory |
| # pages, so fuzzer will not crash when reaching the limit. |
| # Apply this for fuzzing builds only, not for all builds with sanitizers. |
| if (use_libfuzzer || use_afl) { |
| defines += [ "SQLITE_MAX_PAGE_COUNT=16384" ] |
| } |
| } |
| |
| include_dirs = [ "amalgamation" ] |
| |
| configs -= [ "//build/config/compiler:chromium_code" ] |
| configs += [ |
| "//build/config/compiler:no_chromium_code", |
| |
| # Must be after no_chromium_code for warning flags to be ordered |
| # correctly. |
| ":sqlite_warnings", |
| ] |
| |
| if (is_linux) { |
| libs = [ "dl" ] |
| } else if (is_mac || is_ios) { |
| libs = [ |
| "CoreFoundation.framework", |
| "CoreServices.framework", |
| ] |
| } else if (is_android) { |
| defines += [ |
| "SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576", |
| "SQLITE_DEFAULT_AUTOVACUUM=1", |
| "SQLITE_TEMP_STORE=3", |
| "SQLITE_ENABLE_FTS3_BACKWARDS", |
| "DSQLITE_DEFAULT_FILE_FORMAT=4", |
| ] |
| } |
| |
| deps = [ |
| "//third_party/icu", |
| ] |
| } |
| |
| config("sqlite_export") { |
| if (is_component_build && is_win) { |
| defines = [ "SQLITE_API=__declspec(dllimport)" ] |
| } |
| } |
| |
| # This is used to allow the SQLITE_API definition to be different when |
| # building sqlite3.c than it is when clients include sqlite3.h. |
| group("sqlite") { |
| public_deps = [ |
| ":chromium_sqlite3", |
| ] |
| public_configs = [ ":sqlite_export" ] |
| } |
| |
| if (is_linux) { |
| executable("sqlite_shell") { |
| # So shell.c can find the correct sqlite3.h. |
| include_dirs = [ "amalgamation" ] |
| |
| sources = [ |
| "src/src/shell.c", |
| "src/src/shell_icu_linux.c", |
| |
| # Include a dummy c++ file to force linking of libstdc++. |
| "build_as_cpp.cc", |
| ] |
| |
| deps = [ |
| ":sqlite", |
| "//build/config:exe_and_shlib_deps", |
| "//third_party/icu", |
| ] |
| } |
| } |
| } |
| |
| if (use_system_sqlite) { |
| # iOS uses the version of sqlite3 shipped with the system instead of the |
| # version shipped with Chromium. Export a "sqlite" target so the change |
| # can be localized to this file. |
| |
| config("sqlite_config") { |
| defines = [ "USE_SYSTEM_SQLITE" ] |
| if (is_ios) { |
| libs = [ "sqlite3" ] |
| } else { |
| assert(false, "extra flags to use system sqlite3 library missing") |
| } |
| } |
| |
| source_set("sqlite") { |
| public_configs = [ ":sqlite_config" ] |
| if (is_ios) { |
| public_deps = [ |
| ":sqlite_recover", |
| ] |
| deps = [ |
| ":sqlite_regexp", |
| ] |
| } |
| } |
| |
| if (is_ios) { |
| source_set("sqlite_recover") { |
| sources = [ |
| # TODO(shess): Move out of the SQLite source tree, perhaps to ext/. |
| "src/src/recover.c", |
| "src/src/recover.h", |
| "src/src/recover_varint.c", |
| ] |
| } |
| |
| source_set("sqlite_regexp") { |
| defines = [ |
| # Necessary to statically compile the extension. |
| "SQLITE_CORE", |
| "SQLITE_ENABLE_ICU", |
| "SQLITE_ENABLE_MEMORY_MANAGEMENT", |
| ] |
| sources = [ |
| "src/ext/icu/icu.c", |
| ] |
| deps = [ |
| "//third_party/icu", |
| ] |
| if (is_clang) { |
| # src/ext/icu/icu.c uses assert(!"string") which causes warnings about |
| # conversion from string literal to bool. |
| configs -= [ "//build/config/clang:extra_warnings" ] |
| } |
| } |
| } |
| } |
| |
| fuzzer_test("sqlite3_prepare_v2_fuzzer") { |
| sources = [ |
| "fuzz/sqlite3_prepare_v2_fuzzer.cc", |
| ] |
| deps = [ |
| ":sqlite", |
| ] |
| dict = "fuzz/sqlite3_prepare_v2_fuzzer.dict" |
| } |
| |
| fuzzer_test("sqlite3_ossfuzz_fuzzer") { |
| # TODO(mmoroz, shess): remove fuzz/ossfuzz.c after next sqlite3 update. |
| sources = [ |
| "fuzz/ossfuzz.c", |
| ] |
| deps = [ |
| ":sqlite", |
| ] |
| dict = "fuzz/sql.dict" |
| } |