commit
eb1978910d
|
@ -1,4 +0,0 @@
|
|||
ede
|
||||
edn
|
||||
nd
|
||||
tre
|
|
@ -0,0 +1,4 @@
|
|||
ssudo
|
||||
tre
|
||||
ede
|
||||
nd
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout code
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.4.0
|
||||
-
|
||||
name: "Calculate required variables"
|
||||
id: variables
|
||||
|
@ -53,7 +53,7 @@ jobs:
|
|||
|
||||
needs: smoke-tests
|
||||
|
||||
container: ghcr.io/pi-hole/ftl-build:v1.23-${{ matrix.arch }}
|
||||
container: ghcr.io/pi-hole/ftl-build:v1.26-${{ matrix.arch }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
@ -81,6 +81,8 @@ jobs:
|
|||
bin_name: pihole-FTL-armv8-linux-gnueabihf
|
||||
- arch: aarch64
|
||||
bin_name: pihole-FTL-aarch64-linux-gnu
|
||||
- arch: riscv64
|
||||
bin_name: pihole-FTL-riscv64-linux-gnu
|
||||
|
||||
env:
|
||||
CI_ARCH: ${{ matrix.arch }}${{ matrix.arch_extra }}
|
||||
|
@ -88,7 +90,7 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout code
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.4.0
|
||||
-
|
||||
name: "Fix ownership of repository"
|
||||
run: chown -R root .
|
||||
|
@ -131,7 +133,7 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout code
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.4.0
|
||||
-
|
||||
name: Get Binaries built in previous jobs
|
||||
uses: actions/download-artifact@v3.0.2
|
||||
|
|
|
@ -10,10 +10,10 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.4.0
|
||||
-
|
||||
name: Spell-Checking
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
ignore_words_file: .codespellignore
|
||||
skip: ./src/database/sqlite3.c,./src/database/sqlite3.h,./src/database/shell.c,./src/lua,./src/dnsmasq,./src/tre-regex
|
||||
ignore_words_file: .github/.codespellignore
|
||||
skip: ./src/database/sqlite3.c,./src/database/sqlite3.h,./src/database/shell.c,./src/lua,./src/dnsmasq,./src/tre-regex,./.git,./test/libs
|
||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
name: Syncing branches
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3.3.0
|
||||
uses: actions/checkout@v3.4.0
|
||||
- name: Opening pull request
|
||||
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
|
||||
env:
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(PIHOLE_FTL C)
|
||||
|
||||
set(DNSMASQ_VERSION pi-hole-v2.89)
|
||||
set(DNSMASQ_VERSION pi-hole-v2.89-9461807)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -47,6 +47,7 @@ static sqlite3 *gravity_db = NULL;
|
|||
static sqlite3_stmt* table_stmt = NULL;
|
||||
static sqlite3_stmt* auditlist_stmt = NULL;
|
||||
bool gravityDB_opened = false;
|
||||
static bool gravity_abp_format = false;
|
||||
|
||||
// Table names corresponding to the enum defined in gravity-db.h
|
||||
static const char* tablename[] = { "vw_gravity", "vw_blacklist", "vw_whitelist", "vw_regex_blacklist", "vw_regex_whitelist" , "" };
|
||||
|
@ -95,6 +96,40 @@ void gravityDB_forked(void)
|
|||
gravityDB_open();
|
||||
}
|
||||
|
||||
static void gravity_check_ABP_format(void)
|
||||
{
|
||||
// Check if we have a valid ABP format
|
||||
// We do this by checking the "abp_domains" property in the "info" table
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
int rc = sqlite3_prepare_v2(gravity_db,
|
||||
"SELECT value FROM info WHERE property = 'abp_domains';",
|
||||
-1, &stmt, NULL);
|
||||
|
||||
if( rc != SQLITE_OK )
|
||||
{
|
||||
logg("gravity_check_ABP_format() - SQL error prepare: %s", sqlite3_errstr(rc));
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute statement
|
||||
rc = sqlite3_step(stmt);
|
||||
if( rc != SQLITE_ROW )
|
||||
{
|
||||
// No result
|
||||
gravity_abp_format = false;
|
||||
sqlite3_finalize(stmt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get result (SQLite3 stores 1 for TRUE, 0 for FALSE)
|
||||
gravity_abp_format = sqlite3_column_int(stmt, 0) != 0;
|
||||
|
||||
// Finalize statement
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
// Open gravity database
|
||||
bool gravityDB_open(void)
|
||||
{
|
||||
|
@ -194,6 +229,10 @@ bool gravityDB_open(void)
|
|||
logg("gravityDB_open() - Cannot set busy handler: %s", sqlite3_errstr(rc));
|
||||
}
|
||||
|
||||
// Check (and remember in global variable) if there are any ABP-style
|
||||
// entries in the database
|
||||
gravity_check_ABP_format();
|
||||
|
||||
if(config.debug & DEBUG_DATABASE)
|
||||
logg("gravityDB_open(): Successfully opened gravity.db");
|
||||
return true;
|
||||
|
@ -1290,7 +1329,102 @@ enum db_result in_gravity(const char *domain, clientsData *client)
|
|||
if(stmt == NULL)
|
||||
stmt = gravity_stmt->get(gravity_stmt, client->id);
|
||||
|
||||
return domain_in_list(domain, stmt, "gravity", NULL);
|
||||
// Check if domain is exactly in gravity list
|
||||
const enum db_result exact_match = domain_in_list(domain, stmt, "gravity", NULL);
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
logg("Checking if \"%s\" is in gravity: %s",
|
||||
domain, exact_match == FOUND ? "yes" : "no");
|
||||
// Return for anything else than "not found" (e.g. "found" or "list not available")
|
||||
if(exact_match != NOT_FOUND)
|
||||
return exact_match;
|
||||
|
||||
// Return early if we are not supposed to check for ABP-style regex
|
||||
// matches. This needs to be enabled in the config file as it is
|
||||
// computationally expensive and not needed in most cases (HOSTS lists).
|
||||
if(!gravity_abp_format)
|
||||
return NOT_FOUND;
|
||||
|
||||
// Make a copy of the domain we will slowly truncate
|
||||
// while extracting the individual components below
|
||||
char *domainBuf = strdup(domain);
|
||||
|
||||
// Buffer to hold the constructed (sub)domain in ABP format
|
||||
char *abpDomain = calloc(strlen(domain) + 4, sizeof(char));
|
||||
// Prime abp matcher with minimal content
|
||||
strcpy(abpDomain, "||^");
|
||||
|
||||
// Get number of domain parts (equals the number of dots + 1)
|
||||
unsigned int N = 1u;
|
||||
for(const char *p = domain; *p != '\0'; p++)
|
||||
if(*p == '.')
|
||||
N++;
|
||||
|
||||
// Loop over domain parts, building matcher from the TLD
|
||||
// going down into domain and subdomains one by one
|
||||
while(N-- > 0)
|
||||
{
|
||||
// Get domain to the *last* occurrence of '.'
|
||||
char *ptr = strrchr(domainBuf, '.');
|
||||
|
||||
// If there are no '.' left in the domain buffer, we use the
|
||||
// remainder which is the left-most domain component
|
||||
if(ptr == NULL)
|
||||
ptr = domainBuf;
|
||||
|
||||
// Get size of this component...
|
||||
const size_t component_size = strlen(ptr);
|
||||
// ... and use it to create a "gap" of the right size in our ABP
|
||||
// format buffer
|
||||
// Insert the domain component into the gap
|
||||
if(ptr[0] == '.')
|
||||
{
|
||||
// If the component starts with a dot, we need
|
||||
// to skip it when copying it into the ABP buffer
|
||||
// Move excluding initial "||" but including final \0 (strlen-2+1 = strlen-1)
|
||||
memmove(abpDomain+2+component_size-1, abpDomain+2, strlen(abpDomain)-1);
|
||||
// Copy component bytes (excl. trailing null-byte)
|
||||
memcpy(abpDomain+2, ptr+1, component_size-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we copy the component as-is
|
||||
memmove(abpDomain+2+component_size, abpDomain+2, strlen(abpDomain)-1);
|
||||
// Copy component bytes (excl. trailing null-byte)
|
||||
memcpy(abpDomain+2, ptr, component_size);
|
||||
}
|
||||
// Check if the constructed ABP-style domain is in the gravity list
|
||||
const enum db_result abp_match = domain_in_list(abpDomain, stmt, "gravity", NULL);
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
logg("Checking if \"%s\" is in gravity: %s",
|
||||
abpDomain, abp_match == FOUND ? "yes" : "no");
|
||||
// Return for anything else than "not found" (e.g. "found" or "list not available")
|
||||
if(abp_match != NOT_FOUND)
|
||||
{
|
||||
free(domainBuf);
|
||||
free(abpDomain);
|
||||
return abp_match;
|
||||
}
|
||||
// Truncate the domain buffer to the left of the
|
||||
// last dot, effectively removing the last component
|
||||
const ssize_t truncate_pos = strlen(domainBuf)-component_size;
|
||||
if(truncate_pos < 1)
|
||||
// This was already the last iteration
|
||||
break;
|
||||
|
||||
// Put a null-byte at the truncation position
|
||||
domainBuf[truncate_pos] = '\0';
|
||||
|
||||
// Move the ABP buffer to the right by one byte ...
|
||||
memmove(abpDomain+3, abpDomain+2, strlen(abpDomain));
|
||||
// ... and insert '.' for the next iteration
|
||||
abpDomain[2] = '.';
|
||||
}
|
||||
|
||||
free(domainBuf);
|
||||
free(abpDomain);
|
||||
|
||||
// Domain not found in gravity list
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
enum db_result in_blacklist(const char *domain, DNSCacheData *dns_cache, clientsData *client)
|
||||
|
|
1956
src/database/shell.c
1956
src/database/shell.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -146,9 +146,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.40.0"
|
||||
#define SQLITE_VERSION_NUMBER 3040000
|
||||
#define SQLITE_SOURCE_ID "2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318"
|
||||
#define SQLITE_VERSION "3.41.1"
|
||||
#define SQLITE_VERSION_NUMBER 3041001
|
||||
#define SQLITE_SOURCE_ID "2023-03-10 12:13:52 20399f3eda5ec249d147ba9e48da6e87f969d7966a9a896764ca437ff7e737ff"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
@ -563,6 +563,7 @@ SQLITE_API int sqlite3_exec(
|
|||
#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
|
||||
#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8))
|
||||
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
||||
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
|
||||
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
|
||||
|
@ -1175,7 +1176,6 @@ struct sqlite3_io_methods {
|
|||
** in wal mode after the client has finished copying pages from the wal
|
||||
** file to the database file, but before the *-shm file is updated to
|
||||
** record the fact that the pages have been checkpointed.
|
||||
** </ul>
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_EXTERNAL_READER]]
|
||||
** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect
|
||||
|
@ -1188,10 +1188,16 @@ struct sqlite3_io_methods {
|
|||
** the database is not a wal-mode db, or if there is no such connection in any
|
||||
** other process. This opcode cannot be used to detect transactions opened
|
||||
** by clients within the current process, only within other processes.
|
||||
** </ul>
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
|
||||
** Used by the cksmvfs VFS module only.
|
||||
** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the
|
||||
** [checksum VFS shim] only.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
|
||||
** If there is currently no transaction open on the database, and the
|
||||
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
|
||||
** purges the contents of the in-memory page cache. If there is an open
|
||||
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
|
@ -1234,6 +1240,7 @@ struct sqlite3_io_methods {
|
|||
#define SQLITE_FCNTL_CKPT_START 39
|
||||
#define SQLITE_FCNTL_EXTERNAL_READER 40
|
||||
#define SQLITE_FCNTL_CKSM_FILE 41
|
||||
#define SQLITE_FCNTL_RESET_CACHE 42
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
|
@ -2177,7 +2184,7 @@ struct sqlite3_mem_methods {
|
|||
** configuration for a database connection can only be changed when that
|
||||
** connection is not currently using lookaside memory, or in other words
|
||||
** when the "current value" returned by
|
||||
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
|
||||
** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero.
|
||||
** Any attempt to change the lookaside memory configuration when lookaside
|
||||
** memory is in use leaves the configuration unchanged and returns
|
||||
** [SQLITE_BUSY].)^</dd>
|
||||
|
@ -2327,8 +2334,12 @@ struct sqlite3_mem_methods {
|
|||
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
||||
** </ol>
|
||||
** Because resetting a database is destructive and irreversible, the
|
||||
** process requires the use of this obscure API and multiple steps to help
|
||||
** ensure that it does not happen by accident.
|
||||
** process requires the use of this obscure API and multiple steps to
|
||||
** help ensure that it does not happen by accident. Because this
|
||||
** feature must be capable of resetting corrupt databases, and
|
||||
** shutting down virtual tables may require access to that corrupt
|
||||
** storage, the library must abandon any installed virtual tables
|
||||
** without calling their xDestroy() methods.
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
|
||||
|
@ -2667,8 +2678,12 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
|
|||
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
|
||||
** SQL statements is a no-op and has no effect on SQL statements
|
||||
** that are started after the sqlite3_interrupt() call returns.
|
||||
**
|
||||
** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether
|
||||
** or not an interrupt is currently in effect for [database connection] D.
|
||||
*/
|
||||
SQLITE_API void sqlite3_interrupt(sqlite3*);
|
||||
SQLITE_API int sqlite3_is_interrupted(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Is Complete
|
||||
|
@ -3286,8 +3301,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
|
|||
** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
|
||||
** information as is provided by the [sqlite3_profile()] callback.
|
||||
** ^The P argument is a pointer to the [prepared statement] and the
|
||||
** X argument points to a 64-bit integer which is the estimated of
|
||||
** the number of nanosecond that the prepared statement took to run.
|
||||
** X argument points to a 64-bit integer which is approximately
|
||||
** the number of nanoseconds that the prepared statement took to run.
|
||||
** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
|
||||
**
|
||||
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
|
||||
|
@ -3350,7 +3365,7 @@ SQLITE_API int sqlite3_trace_v2(
|
|||
**
|
||||
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
|
||||
** function X to be invoked periodically during long running calls to
|
||||
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
|
||||
** [sqlite3_step()] and [sqlite3_prepare()] and similar for
|
||||
** database connection D. An example use for this
|
||||
** interface is to keep a GUI updated during a large query.
|
||||
**
|
||||
|
@ -3375,6 +3390,13 @@ SQLITE_API int sqlite3_trace_v2(
|
|||
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
|
||||
** database connections for the meaning of "modify" in this paragraph.
|
||||
**
|
||||
** The progress handler callback would originally only be invoked from the
|
||||
** bytecode engine. It still might be invoked during [sqlite3_prepare()]
|
||||
** and similar because those routines might force a reparse of the schema
|
||||
** which involves running the bytecode engine. However, beginning with
|
||||
** SQLite version 3.41.0, the progress handler callback might also be
|
||||
** invoked directly from [sqlite3_prepare()] while analyzing and generating
|
||||
** code for complex queries.
|
||||
*/
|
||||
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
|
||||
|
@ -3411,13 +3433,18 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
|||
**
|
||||
** <dl>
|
||||
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
|
||||
** <dd>The database is opened in read-only mode. If the database does not
|
||||
** already exist, an error is returned.</dd>)^
|
||||
** <dd>The database is opened in read-only mode. If the database does
|
||||
** not already exist, an error is returned.</dd>)^
|
||||
**
|
||||
** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
|
||||
** <dd>The database is opened for reading and writing if possible, or reading
|
||||
** only if the file is write protected by the operating system. In either
|
||||
** case the database must already exist, otherwise an error is returned.</dd>)^
|
||||
** <dd>The database is opened for reading and writing if possible, or
|
||||
** reading only if the file is write protected by the operating
|
||||
** system. In either case the database must already exist, otherwise
|
||||
** an error is returned. For historical reasons, if opening in
|
||||
** read-write mode fails due to OS-level permissions, an attempt is
|
||||
** made to open it in read-only mode. [sqlite3_db_readonly()] can be
|
||||
** used to determine whether the database is actually
|
||||
** read-write.</dd>)^
|
||||
**
|
||||
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
|
||||
** <dd>The database is opened for reading and writing, and is created if
|
||||
|
@ -5398,10 +5425,21 @@ SQLITE_API int sqlite3_create_window_function(
|
|||
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in
|
||||
** schema structures such as [CHECK constraints], [DEFAULT clauses],
|
||||
** [expression indexes], [partial indexes], or [generated columns].
|
||||
** The SQLITE_DIRECTONLY flags is a security feature which is recommended
|
||||
** for all [application-defined SQL functions], and especially for functions
|
||||
** that have side-effects or that could potentially leak sensitive
|
||||
** information.
|
||||
** <p>
|
||||
** The SQLITE_DIRECTONLY flag is recommended for any
|
||||
** [application-defined SQL function]
|
||||
** that has side-effects or that could potentially leak sensitive information.
|
||||
** This will prevent attacks in which an application is tricked
|
||||
** into using a database file that has had its schema surreptiously
|
||||
** modified to invoke the application-defined function in ways that are
|
||||
** harmful.
|
||||
** <p>
|
||||
** Some people say it is good practice to set SQLITE_DIRECTONLY on all
|
||||
** [application-defined SQL functions], regardless of whether or not they
|
||||
** are security sensitive, as doing so prevents those functions from being used
|
||||
** inside of the database schema, and thus ensures that the database
|
||||
** can be inspected and modified using generic tools (such as the [CLI])
|
||||
** that do not have access to the application-defined functions.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
|
||||
|
@ -5542,16 +5580,6 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
|
|||
** then the conversion is performed. Otherwise no conversion occurs.
|
||||
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
|
||||
**
|
||||
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
|
||||
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current encoding
|
||||
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
|
||||
** returns something other than SQLITE_TEXT, then the return value from
|
||||
** sqlite3_value_encoding(X) is meaningless. ^Calls to
|
||||
** sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X),
|
||||
** sqlite3_value_text16le(X), sqlite3_value_bytes(X), or
|
||||
** sqlite3_value_bytes16(X) might change the encoding of the value X and
|
||||
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
|
||||
**
|
||||
** ^Within the [xUpdate] method of a [virtual table], the
|
||||
** sqlite3_value_nochange(X) interface returns true if and only if
|
||||
** the column corresponding to X is unchanged by the UPDATE operation
|
||||
|
@ -5616,6 +5644,27 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*);
|
|||
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
|
||||
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
|
||||
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Report the internal text encoding state of an sqlite3_value object
|
||||
** METHOD: sqlite3_value
|
||||
**
|
||||
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
|
||||
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding
|
||||
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
|
||||
** returns something other than SQLITE_TEXT, then the return value from
|
||||
** sqlite3_value_encoding(X) is meaningless. ^Calls to
|
||||
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)],
|
||||
** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or
|
||||
** [sqlite3_value_bytes16(X)] might change the encoding of the value X and
|
||||
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
|
||||
**
|
||||
** This routine is intended for used by applications that test and validate
|
||||
** the SQLite implementation. This routine is inquiring about the opaque
|
||||
** internal state of an [sqlite3_value] object. Ordinary applications should
|
||||
** not need to know what the internal state of an sqlite3_value object is and
|
||||
** hence should not need to use this interface.
|
||||
*/
|
||||
SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
|
||||
|
||||
/*
|
||||
|
@ -6996,15 +7045,6 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
|
|||
*/
|
||||
SQLITE_API void sqlite3_reset_auto_extension(void);
|
||||
|
||||
/*
|
||||
** The interface to the virtual-table mechanism is currently considered
|
||||
** to be experimental. The interface might change in incompatible ways.
|
||||
** If this is a problem for you, do not use the interface at this time.
|
||||
**
|
||||
** When the virtual-table mechanism stabilizes, we will declare the
|
||||
** interface fixed, support it indefinitely, and remove this comment.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Structures used by the virtual table interface
|
||||
*/
|
||||
|
@ -7123,10 +7163,10 @@ struct sqlite3_module {
|
|||
** when the omit flag is true there is no guarantee that the constraint will
|
||||
** not be checked again using byte code.)^
|
||||
**
|
||||
** ^The idxNum and idxPtr values are recorded and passed into the
|
||||
** ^The idxNum and idxStr values are recorded and passed into the
|
||||
** [xFilter] method.
|
||||
** ^[sqlite3_free()] is used to free idxPtr if and only if
|
||||
** needToFreeIdxPtr is true.
|
||||
** ^[sqlite3_free()] is used to free idxStr if and only if
|
||||
** needToFreeIdxStr is true.
|
||||
**
|
||||
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
|
||||
** the correct order to satisfy the ORDER BY clause so that no separate
|
||||
|
@ -7246,7 +7286,7 @@ struct sqlite3_index_info {
|
|||
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
|
||||
** tables, the collating sequence of constraints does not matter (for example
|
||||
** because the constraints are numeric) and so the sqlite3_vtab_collation()
|
||||
** interface is no commonly needed.
|
||||
** interface is not commonly needed.
|
||||
*/
|
||||
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
||||
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
||||
|
@ -7405,16 +7445,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
|
|||
*/
|
||||
SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
|
||||
|
||||
/*
|
||||
** The interface to the virtual-table mechanism defined above (back up
|
||||
** to a comment remarkably similar to this one) is currently considered
|
||||
** to be experimental. The interface might change in incompatible ways.
|
||||
** If this is a problem for you, do not use the interface at this time.
|
||||
**
|
||||
** When the virtual-table mechanism stabilizes, we will declare the
|
||||
** interface fixed, support it indefinitely, and remove this comment.
|
||||
*/
|
||||
|
||||
/*
|
||||
** CAPI3REF: A Handle To An Open BLOB
|
||||
** KEYWORDS: {BLOB handle} {BLOB handles}
|
||||
|
@ -9618,7 +9648,7 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
|
|||
** <li><p> Otherwise, "BINARY" is returned.
|
||||
** </ol>
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine if a virtual table query is DISTINCT
|
||||
|
@ -9775,21 +9805,20 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
|
|||
** is undefined and probably harmful.
|
||||
**
|
||||
** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
|
||||
** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
|
||||
** sqlite3_vtab_in_next(X,P) should be one of the parameters to the
|
||||
** xFilter method which invokes these routines, and specifically
|
||||
** a parameter that was previously selected for all-at-once IN constraint
|
||||
** processing use the [sqlite3_vtab_in()] interface in the
|
||||
** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
|
||||
** an xFilter argument that was selected for all-at-once IN constraint
|
||||
** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
|
||||
** exhibit some other undefined or harmful behavior.
|
||||
** processing, then these routines return [SQLITE_ERROR].)^
|
||||
**
|
||||
** ^(Use these routines to access all values on the right-hand side
|
||||
** of the IN constraint using code like the following:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
|
||||
** rc==SQLITE_OK && pVal
|
||||
** rc==SQLITE_OK && pVal;
|
||||
** rc=sqlite3_vtab_in_next(pList, &pVal)
|
||||
** ){
|
||||
** // do something with pVal
|
||||
|
@ -9887,6 +9916,10 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
|
|||
** managed by the prepared statement S and will be automatically freed when
|
||||
** S is finalized.
|
||||
**
|
||||
** Not all values are available for all query elements. When a value is
|
||||
** not available, the output variable is set to -1 if the value is numeric,
|
||||
** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
|
||||
** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
|
||||
|
@ -9914,12 +9947,24 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
|
|||
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
|
||||
** description for the X-th loop.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
|
||||
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt>
|
||||
** <dd>^The "int" variable pointed to by the V parameter will be set to the
|
||||
** "select-id" for the X-th loop. The select-id identifies which query or
|
||||
** subquery the loop is part of. The main query has a select-id of zero.
|
||||
** The select-id is the same value as is output in the first column
|
||||
** of an [EXPLAIN QUERY PLAN] query.
|
||||
** id for the X-th query plan element. The id value is unique within the
|
||||
** statement. The select-id is the same value as is output in the first
|
||||
** column of an [EXPLAIN QUERY PLAN] query.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt>
|
||||
** <dd>The "int" variable pointed to by the V parameter will be set to the
|
||||
** the id of the parent of the current query element, if applicable, or
|
||||
** to zero if the query element has no parent. This is the same value as
|
||||
** returned in the second column of an [EXPLAIN QUERY PLAN] query.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt>
|
||||
** <dd>The sqlite3_int64 output value is set to the number of cycles,
|
||||
** according to the processor time-stamp counter, that elapsed while the
|
||||
** query element was being processed. This value is not available for
|
||||
** all query elements - if it is unavailable the output variable is
|
||||
** set to -1.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_SCANSTAT_NLOOP 0
|
||||
|
@ -9928,12 +9973,14 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
|
|||
#define SQLITE_SCANSTAT_NAME 3
|
||||
#define SQLITE_SCANSTAT_EXPLAIN 4
|
||||
#define SQLITE_SCANSTAT_SELECTID 5
|
||||
#define SQLITE_SCANSTAT_PARENTID 6
|
||||
#define SQLITE_SCANSTAT_NCYCLE 7
|
||||
|
||||
/*
|
||||
** CAPI3REF: Prepared Statement Scan Status
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** This interface returns information about the predicted and measured
|
||||
** These interfaces return information about the predicted and measured
|
||||
** performance for pStmt. Advanced applications can use this
|
||||
** interface to compare the predicted and the measured performance and
|
||||
** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
|
||||
|
@ -9944,19 +9991,25 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
|
|||
**
|
||||
** The "iScanStatusOp" parameter determines which status information to return.
|
||||
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
|
||||
** of this interface is undefined.
|
||||
** ^The requested measurement is written into a variable pointed to by
|
||||
** the "pOut" parameter.
|
||||
** Parameter "idx" identifies the specific loop to retrieve statistics for.
|
||||
** Loops are numbered starting from zero. ^If idx is out of range - less than
|
||||
** zero or greater than or equal to the total number of loops used to implement
|
||||
** the statement - a non-zero value is returned and the variable that pOut
|
||||
** points to is unchanged.
|
||||
** of this interface is undefined. ^The requested measurement is written into
|
||||
** a variable pointed to by the "pOut" parameter.
|
||||
**
|
||||
** ^Statistics might not be available for all loops in all statements. ^In cases
|
||||
** where there exist loops with no available statistics, this function behaves
|
||||
** as if the loop did not exist - it returns non-zero and leave the variable
|
||||
** that pOut points to unchanged.
|
||||
** The "flags" parameter must be passed a mask of flags. At present only
|
||||
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
|
||||
** is specified, then status information is available for all elements
|
||||
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
|
||||
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
|
||||
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
|
||||
** the EXPLAIN QUERY PLAN output) are available. Invoking API
|
||||
** sqlite3_stmt_scanstatus() is equivalent to calling
|
||||
** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
|
||||
**
|
||||
** Parameter "idx" identifies the specific query element to retrieve statistics
|
||||
** for. Query elements are numbered starting from zero. A value of -1 may be
|
||||
** to query for statistics regarding the entire query. ^If idx is out of range
|
||||
** - less than -1 or greater than or equal to the total number of query
|
||||
** elements used to implement the statement - a non-zero value is returned and
|
||||
** the variable that pOut points to is unchanged.
|
||||
**
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()]
|
||||
*/
|
||||
|
@ -9966,6 +10019,19 @@ SQLITE_API int sqlite3_stmt_scanstatus(
|
|||
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
|
||||
void *pOut /* Result written here */
|
||||
);
|
||||
SQLITE_API int sqlite3_stmt_scanstatus_v2(
|
||||
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
|
||||
int idx, /* Index of loop to report on */
|
||||
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
|
||||
int flags, /* Mask of flags defined below */
|
||||
void *pOut /* Result written here */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Prepared Statement Scan Status
|
||||
** KEYWORDS: {scan status flags}
|
||||
*/
|
||||
#define SQLITE_SCANSTAT_COMPLEX 0x0001
|
||||
|
||||
/*
|
||||
** CAPI3REF: Zero Scan-Status Counters
|
||||
|
@ -10056,6 +10122,10 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
|
|||
** function is not defined for operations on WITHOUT ROWID tables, or for
|
||||
** DELETE operations on rowid tables.
|
||||
**
|
||||
** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from
|
||||
** the previous call on the same [database connection] D, or NULL for
|
||||
** the first call on D.
|
||||
**
|
||||
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
|
||||
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
|
||||
** provide additional information about a preupdate event. These routines
|
||||
|
@ -10461,6 +10531,19 @@ SQLITE_API int sqlite3_deserialize(
|
|||
# undef double
|
||||
#endif
|
||||
|
||||
#if defined(__wasi__)
|
||||
# undef SQLITE_WASI
|
||||
# define SQLITE_WASI 1
|
||||
# undef SQLITE_OMIT_WAL
|
||||
# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */
|
||||
# ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
# define SQLITE_OMIT_LOAD_EXTENSION
|
||||
# endif
|
||||
# ifndef SQLITE_THREADSAFE
|
||||
# define SQLITE_THREADSAFE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define CHILD_LIFETIME 300 /* secs 'till terminated (RFC1035 suggests > 120s) */
|
||||
#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
|
||||
#define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
|
||||
#define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */
|
||||
#define EDNS_PKTSZ 1232 /* default max EDNS.0 UDP packet from from /dnsflagday.net/2020 */
|
||||
#define SAFE_PKTSZ 1232 /* "go anywhere" UDP packet size, see https://dnsflagday.net/2020/ */
|
||||
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
|
||||
#define DNSSEC_WORK 50 /* Max number of queries to validate one question */
|
||||
|
|
|
@ -52,6 +52,12 @@ const char* introspection_xml_template =
|
|||
" <method name=\"SetFilterWin2KOption\">\n"
|
||||
" <arg name=\"filterwin2k\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetFilterA\">\n"
|
||||
" <arg name=\"filter-a\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetFilterAAAA\">\n"
|
||||
" <arg name=\"filter-aaaa\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetLocaliseQueriesOption\">\n"
|
||||
" <arg name=\"localise-queries\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
|
@ -817,6 +823,14 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
|||
{
|
||||
reply = dbus_set_bool(message, OPT_FILTER, "filterwin2k");
|
||||
}
|
||||
else if (strcmp(method, "SetFilterA") == 0)
|
||||
{
|
||||
reply = dbus_set_bool(message, OPT_FILTER_A, "filter-A");
|
||||
}
|
||||
else if (strcmp(method, "SetFilterAAAA") == 0)
|
||||
{
|
||||
reply = dbus_set_bool(message, OPT_FILTER_AAAA, "filter-AAAA");
|
||||
}
|
||||
else if (strcmp(method, "SetLocaliseQueriesOption") == 0)
|
||||
{
|
||||
reply = dbus_set_bool(message, OPT_LOCALISE, "localise-queries");
|
||||
|
|
|
@ -838,7 +838,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
|
|||
for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)
|
||||
{
|
||||
char c = val[i];
|
||||
if (isprint((int)c))
|
||||
if (isprint((unsigned char)c))
|
||||
buf[j++] = c;
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
|
@ -852,7 +852,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
|
|||
for (k = i + 1; k < opt_len && k < l && j < buf_len ; k++)
|
||||
{
|
||||
char c = val[k];
|
||||
if (isprint((int)c))
|
||||
if (isprint((unsigned char)c))
|
||||
buf[j++] = c;
|
||||
}
|
||||
i = l;
|
||||
|
@ -873,7 +873,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
|
|||
for (k = 0; k < len && j < buf_len; k++)
|
||||
{
|
||||
char c = *p++;
|
||||
if (isprint((int)c))
|
||||
if (isprint((unsigned char)c))
|
||||
buf[j++] = c;
|
||||
}
|
||||
i += len +2;
|
||||
|
|
|
@ -916,14 +916,14 @@ void dhcp_read_ethers(void)
|
|||
|
||||
lineno++;
|
||||
|
||||
while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
|
||||
while (strlen(buff) > 0 && isspace((unsigned char)buff[strlen(buff)-1]))
|
||||
buff[strlen(buff)-1] = 0;
|
||||
|
||||
if ((*buff == '#') || (*buff == '+') || (*buff == 0))
|
||||
continue;
|
||||
|
||||
for (ip = buff; *ip && !isspace((int)*ip); ip++);
|
||||
for(; *ip && isspace((int)*ip); ip++)
|
||||
for (ip = buff; *ip && !isspace((unsigned char)*ip); ip++);
|
||||
for(; *ip && isspace((unsigned char)*ip); ip++)
|
||||
*ip = 0;
|
||||
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
|
||||
{
|
||||
|
|
|
@ -253,9 +253,10 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
|
|||
if (highout)
|
||||
*highout = nhigh;
|
||||
|
||||
if (nlow == nhigh)
|
||||
/* qlen == -1 when we failed to match even an empty query, if there are no default servers. */
|
||||
if (nlow == nhigh || qlen == -1)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ int detect_loop(char *query, int type)
|
|||
return 0;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!isxdigit(query[i]))
|
||||
if (!isxdigit((unsigned char)query[i]))
|
||||
return 0;
|
||||
|
||||
uid = strtol(query, NULL, 16);
|
||||
|
|
|
@ -361,13 +361,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||
struct in_addr newaddr = addr->in.sin_addr;
|
||||
|
||||
if (int_name->flags & INP4)
|
||||
{
|
||||
if (netmask.s_addr == 0xffffffff)
|
||||
continue;
|
||||
|
||||
newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) |
|
||||
(int_name->proto4.s_addr & ~netmask.s_addr);
|
||||
}
|
||||
newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) |
|
||||
(int_name->proto4.s_addr & ~netmask.s_addr);
|
||||
|
||||
/* check for duplicates. */
|
||||
for (lp = int_name->addr; lp; lp = lp->next)
|
||||
|
@ -400,10 +395,6 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||
{
|
||||
int i;
|
||||
|
||||
/* No sense in doing /128. */
|
||||
if (prefixlen == 128)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
int bits = ((i+1)*8) - prefixlen;
|
||||
|
|
|
@ -1163,6 +1163,9 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Always reset server as valid here, so we can add the same upstream
|
||||
server address multiple times for each x.y.z.in-addr.arpa */
|
||||
sdetails.valid = 1;
|
||||
while (parse_server_next(&sdetails))
|
||||
{
|
||||
if ((string = parse_server_addr(&sdetails)))
|
||||
|
@ -1248,6 +1251,9 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Always reset server as valid here, so we can add the same upstream
|
||||
server address multiple times for each x.y.z.ip6.arpa */
|
||||
sdetails.valid = 1;
|
||||
while (parse_server_next(&sdetails))
|
||||
{
|
||||
if ((string = parse_server_addr(&sdetails)))
|
||||
|
@ -2755,7 +2761,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||
ret_err(gen_err);
|
||||
|
||||
for (p = arg; *p; p++)
|
||||
if (!isxdigit((int)*p))
|
||||
if (!isxdigit((unsigned char)*p))
|
||||
ret_err(gen_err);
|
||||
|
||||
set_option_bool(OPT_UMBRELLA_DEVID);
|
||||
|
@ -4840,7 +4846,7 @@ err:
|
|||
new->target = target;
|
||||
new->ttl = ttl;
|
||||
|
||||
for (arg += arglen+1; *arg && isspace(*arg); arg++);
|
||||
for (arg += arglen+1; *arg && isspace((unsigned char)*arg); arg++);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -5231,7 +5237,7 @@ err:
|
|||
unhide_metas(keyhex);
|
||||
/* 4034: "Whitespace is allowed within digits" */
|
||||
for (cp = keyhex; *cp; )
|
||||
if (isspace(*cp))
|
||||
if (isspace((unsigned char)*cp))
|
||||
for (cp1 = cp; *cp1; cp1++)
|
||||
*cp1 = *(cp1+1);
|
||||
else
|
||||
|
@ -5319,7 +5325,7 @@ static void read_file(char *file, FILE *f, int hard_opt, int from_script)
|
|||
memmove(p, p+1, strlen(p+1)+1);
|
||||
}
|
||||
|
||||
if (isspace(*p))
|
||||
if (isspace((unsigned char)*p))
|
||||
{
|
||||
*p = ' ';
|
||||
white = 1;
|
||||
|
@ -5879,12 +5885,10 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
|||
add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
|
||||
/* Pi-hole modification */
|
||||
add_txt("privacylevel.pihole", NULL, TXT_PRIVACYLEVEL);
|
||||
add_txt("version.FTL", (char*)get_FTL_version(), 0 );
|
||||
/************************/
|
||||
}
|
||||
#endif
|
||||
/******** Pi-hole modification ********/
|
||||
add_txt("version.FTL", (char*)get_FTL_version(), 0 );
|
||||
/**************************************/
|
||||
|
||||
/* port might not be known when the address is parsed - fill in here */
|
||||
if (daemon->servers)
|
||||
|
|
|
@ -520,7 +520,7 @@ static int print_txt(struct dns_header *header, const size_t qlen, char *name,
|
|||
/* make counted string zero-term and sanitise */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!isprint((int)*(p3+1)))
|
||||
if (!isprint((unsigned char)*(p3+1)))
|
||||
break;
|
||||
*p3 = *(p3+1);
|
||||
p3++;
|
||||
|
@ -907,9 +907,8 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||
{
|
||||
flags &= ~(F_IPV4 | F_IPV6 | F_SRV);
|
||||
|
||||
/* Can store NXDOMAIN reply to CNAME or ANY query. */
|
||||
if (qtype == T_CNAME || qtype == T_ANY)
|
||||
insert = 1;
|
||||
/* Can store NXDOMAIN reply for any qtype. */
|
||||
insert = 1;
|
||||
}
|
||||
|
||||
log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL, 0);
|
||||
|
@ -2109,7 +2108,22 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||
}
|
||||
|
||||
if (!ans)
|
||||
return 0; /* failed to answer a question */
|
||||
{
|
||||
/* We may know that the domain doesn't exist for any RRtype. */
|
||||
if ((crecp = cache_find_by_name(NULL, name, now, F_NXDOMAIN)))
|
||||
{
|
||||
ans = nxdomain = 1;
|
||||
auth = 0;
|
||||
|
||||
if (!(crecp->flags & F_DNSSECOK))
|
||||
sec_data = 0;
|
||||
|
||||
if (!dryrun)
|
||||
log_query(F_NXDOMAIN | F_NEG, name, NULL, NULL, 0);
|
||||
}
|
||||
else
|
||||
return 0; /* failed to answer a question */
|
||||
}
|
||||
}
|
||||
|
||||
if (dryrun)
|
||||
|
|
|
@ -1678,7 +1678,7 @@ static int sanitise(unsigned char *opt, char *buf)
|
|||
for (i = option_len(opt); i > 0; i--)
|
||||
{
|
||||
char c = *p++;
|
||||
if (isprint((int)c))
|
||||
if (isprint((unsigned char)c))
|
||||
*buf++ = c;
|
||||
}
|
||||
*buf = 0; /* add terminator */
|
||||
|
|
|
@ -353,7 +353,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
|||
put_opt6_short(DHCP6USEMULTI);
|
||||
put_opt6_string("Use multicast");
|
||||
end_opt6(o1);
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* match vendor and user class options */
|
||||
|
@ -1277,12 +1277,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
|||
|
||||
}
|
||||
|
||||
log_tags(tagif, state->xid);
|
||||
|
||||
done:
|
||||
/* Fill in the message type. Note that we store the offset,
|
||||
not a direct pointer, since the packet memory may have been
|
||||
reallocated. */
|
||||
((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
|
||||
|
||||
log_tags(tagif, state->xid);
|
||||
log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -405,7 +405,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||
if (*p == '\\')
|
||||
*p = '/';
|
||||
else if (option_bool(OPT_TFTP_LC))
|
||||
*p = tolower(*p);
|
||||
*p = tolower((unsigned char)*p);
|
||||
|
||||
strcpy(daemon->namebuff, "/");
|
||||
if (prefix)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
// EDNS(0) Client Subnet [Optional, RFC7871]
|
||||
#define EDNS0_ECS EDNS0_OPTION_CLIENT_SUBNET
|
||||
|
||||
// EDN(0) COOKIE [Standard, RFC7873]
|
||||
// EDNS(0) COOKIE [Standard, RFC7873]
|
||||
#define EDNS0_COOKIE 10
|
||||
|
||||
// EDNS(0) MAC address [NOT STANDARDIZED]
|
||||
|
|
|
@ -333,13 +333,13 @@ const char __attribute__ ((const)) *get_ordinal_suffix(unsigned int number)
|
|||
// If the tens digit is not equal to 1, then the following table could be used:
|
||||
switch (number % 10)
|
||||
{
|
||||
case 1: // If the units digit is 1: This is written after the number "st"
|
||||
case 1: // If the units digit is 1: This is written after the number "1st"
|
||||
return "st";
|
||||
case 2: // If the units digit is 2: This is written after the number "nd"
|
||||
case 2: // If the units digit is 2: This is written after the number "2nd"
|
||||
return "nd";
|
||||
case 3: // If the units digit is 3: This is written after the number "rd"
|
||||
case 3: // If the units digit is 3: This is written after the number "3rd"
|
||||
return "rd";
|
||||
default: // If the units digit is 0 or 4-9: This is written after the number "th"
|
||||
default: // If the units digit is 0 or 4-9: This is written after the number "9th"
|
||||
return "th";
|
||||
}
|
||||
// For example: 2nd, 7th, 20th, 23rd, 52nd, 135th, 301st BUT 311th (covered above)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
extern const char *regextype[];
|
||||
|
||||
// Use TRE instead of GNU regex library (compiled into FTL itself)
|
||||
// Use TRE-Engine instead of GNU/MUSL regex libraries
|
||||
#define USE_TRE_REGEX
|
||||
|
||||
#ifdef USE_TRE_REGEX
|
||||
|
|
|
@ -29,6 +29,9 @@ int check_one_struct(const char *struct_name, const size_t found_size, const siz
|
|||
#elif defined(__arm__)
|
||||
const size_t expected_size = size32;
|
||||
const char *arch = "arm";
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
const size_t expected_size = size64;
|
||||
const char *arch = "riscv64";
|
||||
#else
|
||||
const size_t expected_size = 0;
|
||||
const char *arch = NULL;
|
||||
|
|
|
@ -147,6 +147,12 @@ elif [[ "${CI_ARCH}" == "armv8a" ]]; then
|
|||
check_CPU_arch "v8"
|
||||
check_FP_arch "VFPv3-D16"
|
||||
|
||||
elif [[ "${CI_ARCH}" == "riscv64" ]]; then
|
||||
|
||||
check_machine "ELF64" "RISC-V"
|
||||
check_libs "[libm.so.6] [libc.so.6] [ld-linux-riscv64-lp64d.so.1]"
|
||||
check_file "ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, with debug_info, not stripped"
|
||||
|
||||
else
|
||||
|
||||
echo "Invalid job ${CI_ARCH}"
|
||||
|
|
|
@ -220,7 +220,9 @@ INSERT INTO gravity VALUES('whitelisted.ftl',1);
|
|||
INSERT INTO gravity VALUES('gravity.ftl',1);
|
||||
INSERT INTO gravity VALUES('gravity-aaaa.ftl',1);
|
||||
INSERT INTO gravity VALUES('gravity-whitelisted.ftl',1);
|
||||
INSERT INTO info VALUES('gravity_count',4);
|
||||
INSERT INTO gravity VALUES('||special.gravity.ftl^',1);
|
||||
INSERT INTO info VALUES('gravity_count',5);
|
||||
INSERT INTO info VALUES('abp_domains',1);
|
||||
|
||||
INSERT INTO "group" VALUES(1,0,'Test group',1559928803,1559928803,'A disabled test group');
|
||||
INSERT INTO domainlist_by_group VALUES(15,1);
|
||||
|
|
|
@ -426,14 +426,25 @@
|
|||
[[ ${lines[@]} == *"status: SERVFAIL"* ]]
|
||||
}
|
||||
|
||||
@test "ABP-style matching working as expected" {
|
||||
run bash -c "dig A special.gravity.ftl @127.0.0.1 +short"
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[0]} == "0.0.0.0" ]]
|
||||
[[ ${lines[1]} == "" ]]
|
||||
run bash -c "dig A a.b.c.d.special.gravity.ftl @127.0.0.1 +short"
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[0]} == "0.0.0.0" ]]
|
||||
[[ ${lines[1]} == "" ]]
|
||||
}
|
||||
|
||||
@test "Statistics as expected" {
|
||||
run bash -c 'echo ">stats >quit" | nc -v 127.0.0.1 4711'
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[1]} == "domains_being_blocked 4" ]]
|
||||
[[ ${lines[2]} == "dns_queries_today 52" ]]
|
||||
[[ ${lines[3]} == "ads_blocked_today 13" ]]
|
||||
[[ ${lines[1]} == "domains_being_blocked 5" ]]
|
||||
[[ ${lines[2]} == "dns_queries_today 54" ]]
|
||||
[[ ${lines[3]} == "ads_blocked_today 15" ]]
|
||||
#[[ ${lines[4]} == "ads_percentage_today 7.792208" ]]
|
||||
[[ ${lines[5]} == "unique_domains 37" ]]
|
||||
[[ ${lines[5]} == "unique_domains 39" ]]
|
||||
[[ ${lines[6]} == "queries_forwarded 27" ]]
|
||||
[[ ${lines[7]} == "queries_cached 12" ]]
|
||||
# Clients ever seen is commented out as the CI may have
|
||||
|
@ -441,12 +452,12 @@
|
|||
# number of clients may not work in all cases
|
||||
#[[ ${lines[8]} == "clients_ever_seen 8" ]]
|
||||
#[[ ${lines[9]} == "unique_clients 8" ]]
|
||||
[[ ${lines[10]} == "dns_queries_all_types 52" ]]
|
||||
[[ ${lines[10]} == "dns_queries_all_types 54" ]]
|
||||
[[ ${lines[11]} == "reply_UNKNOWN 0" ]]
|
||||
[[ ${lines[12]} == "reply_NODATA 0" ]]
|
||||
[[ ${lines[13]} == "reply_NXDOMAIN 1" ]]
|
||||
[[ ${lines[14]} == "reply_CNAME 7" ]]
|
||||
[[ ${lines[15]} == "reply_IP 23" ]]
|
||||
[[ ${lines[15]} == "reply_IP 25" ]]
|
||||
[[ ${lines[16]} == "reply_DOMAIN 0" ]]
|
||||
[[ ${lines[17]} == "reply_RRNAME 5" ]]
|
||||
[[ ${lines[18]} == "reply_SERVFAIL 0" ]]
|
||||
|
@ -456,7 +467,7 @@
|
|||
[[ ${lines[22]} == "reply_DNSSEC 6" ]]
|
||||
[[ ${lines[23]} == "reply_NONE 0" ]]
|
||||
[[ ${lines[24]} == "reply_BLOB 10" ]]
|
||||
[[ ${lines[25]} == "dns_queries_all_replies 52" ]]
|
||||
[[ ${lines[25]} == "dns_queries_all_replies 54" ]]
|
||||
[[ ${lines[26]} == "privacy_level 0" ]]
|
||||
[[ ${lines[27]} == "status enabled" ]]
|
||||
[[ ${lines[28]} == "" ]]
|
||||
|
@ -471,7 +482,7 @@
|
|||
@test "Top Clients" {
|
||||
run bash -c 'echo ">top-clients >quit" | nc -v 127.0.0.1 4711'
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[1]} == "0 36 127.0.0.1 "* ]]
|
||||
[[ ${lines[1]} == "0 38 127.0.0.1 "* ]]
|
||||
[[ ${lines[2]} == "1 6 :: "* ]]
|
||||
[[ ${lines[3]} == "2 4 127.0.0.3 "* ]]
|
||||
[[ ${lines[4]} == "3 3 127.0.0.2 "* ]]
|
||||
|
@ -519,12 +530,14 @@
|
|||
[[ "${lines[@]}" == *" 2 gravity-aaaa.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 blacklisted.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 whitelisted.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 special.gravity.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 a.b.c.d.special.gravity.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 regex5.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 regex1.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 cname-1.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 cname-7.ftl"* ]]
|
||||
[[ "${lines[@]}" == *" 1 use-application-dns.net"* ]]
|
||||
[[ ${lines[12]} == "" ]]
|
||||
[[ ${lines[14]} == "" ]]
|
||||
}
|
||||
|
||||
@test "Domain auditing, approved domains are not shown" {
|
||||
|
@ -542,33 +555,33 @@
|
|||
@test "Upstream Destinations reported correctly" {
|
||||
run bash -c 'echo ">forward-dest >quit" | nc -v 127.0.0.1 4711'
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[1]} == "-3 25.00 blocked blocked" ]]
|
||||
[[ ${lines[2]} == "-2 23.08 cached cached" ]]
|
||||
[[ ${lines[1]} == "-3 27.78 blocked blocked" ]]
|
||||
[[ ${lines[2]} == "-2 22.22 cached cached" ]]
|
||||
[[ ${lines[3]} == "-1 0.00 other other" ]]
|
||||
[[ ${lines[4]} == "0 48.08 127.0.0.1#5555 127.0.0.1#5555" ]]
|
||||
[[ ${lines[5]} == "1 3.85 127.0.0.1#5554 127.0.0.1#5554" ]]
|
||||
[[ ${lines[4]} == "0 46.30 127.0.0.1#5555 127.0.0.1#5555" ]]
|
||||
[[ ${lines[5]} == "1 3.70 127.0.0.1#5554 127.0.0.1#5554" ]]
|
||||
[[ ${lines[6]} == "" ]]
|
||||
}
|
||||
|
||||
@test "Query Types reported correctly" {
|
||||
run bash -c 'echo ">querytypes >quit" | nc -v 127.0.0.1 4711'
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[1]} == "A (IPv4): 50.00" ]]
|
||||
[[ ${lines[2]} == "AAAA (IPv6): 7.69" ]]
|
||||
[[ ${lines[3]} == "ANY: 1.92" ]]
|
||||
[[ ${lines[4]} == "SRV: 1.92" ]]
|
||||
[[ ${lines[5]} == "SOA: 1.92" ]]
|
||||
[[ ${lines[6]} == "PTR: 1.92" ]]
|
||||
[[ ${lines[7]} == "TXT: 11.54" ]]
|
||||
[[ ${lines[8]} == "NAPTR: 1.92" ]]
|
||||
[[ ${lines[9]} == "MX: 1.92" ]]
|
||||
[[ ${lines[10]} == "DS: 5.77" ]]
|
||||
[[ ${lines[1]} == "A (IPv4): 51.85" ]]
|
||||
[[ ${lines[2]} == "AAAA (IPv6): 7.41" ]]
|
||||
[[ ${lines[3]} == "ANY: 1.85" ]]
|
||||
[[ ${lines[4]} == "SRV: 1.85" ]]
|
||||
[[ ${lines[5]} == "SOA: 1.85" ]]
|
||||
[[ ${lines[6]} == "PTR: 1.85" ]]
|
||||
[[ ${lines[7]} == "TXT: 11.11" ]]
|
||||
[[ ${lines[8]} == "NAPTR: 1.85" ]]
|
||||
[[ ${lines[9]} == "MX: 1.85" ]]
|
||||
[[ ${lines[10]} == "DS: 5.56" ]]
|
||||
[[ ${lines[11]} == "RRSIG: 0.00" ]]
|
||||
[[ ${lines[12]} == "DNSKEY: 5.77" ]]
|
||||
[[ ${lines[13]} == "NS: 1.92" ]]
|
||||
[[ ${lines[14]} == "OTHER: 1.92" ]]
|
||||
[[ ${lines[15]} == "SVCB: 1.92" ]]
|
||||
[[ ${lines[16]} == "HTTPS: 1.92" ]]
|
||||
[[ ${lines[12]} == "DNSKEY: 5.56" ]]
|
||||
[[ ${lines[13]} == "NS: 1.85" ]]
|
||||
[[ ${lines[14]} == "OTHER: 1.85" ]]
|
||||
[[ ${lines[15]} == "SVCB: 1.85" ]]
|
||||
[[ ${lines[16]} == "HTTPS: 1.85" ]]
|
||||
[[ ${lines[17]} == "" ]]
|
||||
}
|
||||
|
||||
|
@ -629,7 +642,9 @@
|
|||
[[ ${lines[50]} == *" DNSKEY dnssec.works :: 2 1 11 "*" N/A -1 127.0.0.1#5555 \"\" \"49\""* ]]
|
||||
[[ ${lines[51]} == *" A fail01.dnssec.works 127.0.0.1 2 3 4 "*" N/A -1 127.0.0.1#5555 \"RRSIG missing\" \"50\""* ]]
|
||||
[[ ${lines[52]} == *" DS fail01.dnssec.works :: 2 1 11 "*" N/A -1 127.0.0.1#5555 \"\" \"51\""* ]]
|
||||
[[ ${lines[53]} == "" ]]
|
||||
[[ ${lines[53]} == *" A special.gravity.ftl 127.0.0.1 1 2 4 "*" N/A -1 N/A#0 \"\" \"52\""* ]]
|
||||
[[ ${lines[54]} == *" A a.b.c.d.special.gravity.ftl 127.0.0.1 1 2 4 "*" N/A -1 N/A#0 \"\" \"53\""* ]]
|
||||
[[ ${lines[55]} == "" ]]
|
||||
}
|
||||
|
||||
@test "Get all queries (domain filtered) shows expected content" {
|
||||
|
@ -642,7 +657,7 @@
|
|||
@test "Recent blocked shows expected content" {
|
||||
run bash -c 'echo ">recentBlocked >quit" | nc -v 127.0.0.1 4711'
|
||||
printf "%s\n" "${lines[@]}"
|
||||
[[ ${lines[1]} == "aaaa-cname.ftl" ]]
|
||||
[[ ${lines[1]} == "a.b.c.d.special.gravity.ftl" ]]
|
||||
[[ ${lines[2]} == "" ]]
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue