# 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_fuzzing_engine) { 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" }