Compare commits

...

1 Commits

Author SHA1 Message Date
numist cce3c0111f Initial exploration of blocky APIs, starting with a variant of sqlite3_exec.
FossilOrigin-Name: fd849d5b6a891c57facbfbba1de855b4349577dbc7afaa7f503e23bc4ca74e8f
2019-12-13 22:59:38 +00:00
5 changed files with 149 additions and 29 deletions
+12 -9
View File
@@ -1,5 +1,5 @@
C Patch\sto\sthe\spage\scache\sto\savoid\sharmless\spointer\sarithmetic\sthat\sdue\sto\sbugs\nin\sthe\sSTD-C\sspec\sis\stechnically\sUB.\s\sThis\sis\sto\sfix\sa\sharmless\sUBSAN\ncomplaint\sthat\sOSSFuzz\sis\shitting.
D 2019-12-13T21:24:46.081
C Initial\sexploration\sof\sblocky\sAPIs,\sstarting\swith\sa\svariant\sof\ssqlite3_exec.
D 2019-12-13T22:59:38.851
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -489,7 +489,7 @@ F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 5de3fd62bd1a692353c8f9c7bbde658f0b579f195620ca3cde1948a53015dddd
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/legacy.c 70ff0890930967fa02a792d3b2c48208eb6a1c4d9f55a465a664b2ddc8b044a4
F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da
F src/main.c 868ae7db7a54fe859bf2ca8b7a4f24e9fa03a6134abfb7c9801d08411ef5dacb
F src/malloc.c 550021fcae36f0ffe9f8563d83e6385f9df307a854d55d7d0abb7241ee8dbcc6
@@ -529,10 +529,10 @@ F src/resolve.c 86a7773d2892227ba9ad1721c41bb03c501830f1bf6de5f78dd0062b82e10c9d
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 0fe10579de20eb8dc04ec9ed29659fa782bee2bcc85a35734637f3e2cabc2762
F src/shell.c.in 4a3a9e1c11847b1904f2b01d087af1c052f660902755abab457cab1756817ded
F src/sqlite.h.in 2a23e8161775253d9cf383c2c6aa559005dc787d350dcb0be67a6c4cc3bd1d19
F src/sqlite.h.in 44a53119d3fb6e2d855d8bfd4b94151338563a2fbe28638e3a24ee8d9e661ae1
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2
F src/sqliteInt.h 60d92fad64da7c3e77bbc35ee306340814cdaa5df32892b0ec58d306d99b5733
F src/sqliteInt.h 6326f05f5924e779f5c3ba422f85adfdef38dbf1012be7d5e40a2d78d4d1a648
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1852,7 +1852,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P c1014e80b26131200a115beb86929a8f0ded2dd65b075e47373346c0f170576a
R b59b4afd4c4fcaeb80758977b1b63c0a
U drh
Z 4fa57844859159ee82f87f0f14b6814f
P c29fc21288e37f81a1617c5e2961c575d3bca6a1d1b013b2e0a99774afb1dcdb
R e55adf2fcddc384393004665528a6995
T *branch * blocky-exec
T *sym-blocky-exec *
T -sym-trunk *
U numist
Z 7fe9b43d252eee701000e10996724092
+1 -1
View File
@@ -1 +1 @@
c29fc21288e37f81a1617c5e2961c575d3bca6a1d1b013b2e0a99774afb1dcdb
fd849d5b6a891c57facbfbba1de855b4349577dbc7afaa7f503e23bc4ca74e8f
+78
View File
@@ -139,3 +139,81 @@ exec_out:
sqlite3_mutex_leave(db->mutex);
return rc;
}
#if SQLITE_HAS_BLOCKS
int sqlite3_exec_b(
sqlite3 *db,
const char *zSql,
int (^xCallback)(sqlite3_stmt *)
){
int rc = SQLITE_OK; /* Return code */
const char *zLeftover; /* Tail of unprocessed SQL */
sqlite3_stmt *pStmt = 0; /* The current SQL statement */
const char **azCols = 0; /* Names of result columns */
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
if( zSql==0 ) zSql = "";
#ifdef SQLITE_ENABLE_SQLRR
SRRecExec(db, zSql);
#endif
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK);
while( rc==SQLITE_OK && zSql[0] ){
int callbackIsInit = 0;
pStmt = 0;
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
}
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
continue;
}
while( 1 ){
rc = sqlite3_step(pStmt);
/* Invoke the callback function if required */
if( xCallback && (SQLITE_ROW==rc ||
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( xCallback(pStmt) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
** sqlite3_exec() returns non-zero, then sqlite3_exec() will
** return SQLITE_ABORT. */
rc = SQLITE_ABORT;
(void)sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
sqlite3Error(db, rc);
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
zSql = zLeftover;
while( sqlite3Isspace(zSql[0]) ) zSql++;
break;
}
}
}
exec_out:
if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
sqlite3DbFree(db, azCols);
#ifdef SQLITE_ENABLE_SQLRR
SRRecExecEnd(db);
#endif
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif
+47 -19
View File
@@ -34,6 +34,15 @@
#define SQLITE3_H
#include <stdarg.h> /* Needed for the definition of va_list */
/* Compatibility with non-clang compilers */
#ifndef __has_feature
# define __has_feature(x) 0
#endif
/* Compatibility with pre-3.0 versions of clang */
#ifndef __has_extension
# define __has_extension __has_feature
#endif
/*
** Make sure we can call this stuff from C++.
*/
@@ -66,6 +75,13 @@ extern "C" {
#ifndef SQLITE_SYSAPI
# define SQLITE_SYSAPI
#endif
#ifndef SQLITE_NOESCAPE
# if __has_feature(noescape)
# define SQLITE_NOESCAPE __attribute__((noescape))
# else
# define SQLITE_NOESCAPE
# endif
#endif
/*
** These no-op macros are used in front of interfaces to mark those
@@ -345,21 +361,20 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** CAPI3REF: One-Step Query Execution Interface
** METHOD: sqlite3
**
** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
** The sqlite3_exec() and sqlite3_exec_b() interfaces are convenience wrappers
** around [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code.
**
** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
** semicolon-separate SQL statements passed into its 2nd argument,
** in the context of the [database connection] passed in as its 1st
** argument. ^If the callback function of the 3rd argument to
** sqlite3_exec() is not NULL, then it is invoked for each result row
** ^The sqlite3_exec() and sqlite3_exec_b() interfaces run zero or more UTF-8
** encoded, semicolon-separate SQL statements passed into their 2nd argument,
** in the context of the [database connection] passed in to their 1st
** argument. ^If the callback function of the 3rd argument to sqlite3_exec()
** or sqlite3_exec_b() is not NULL, then it is invoked for each result row
** coming out of the evaluated SQL statements. ^The 4th argument to
** sqlite3_exec() is relayed through to the 1st argument of each
** callback invocation. ^If the callback pointer to sqlite3_exec()
** is NULL, then no callback is ever invoked and result rows are
** ignored.
** sqlite3_exec() is relayed through to the 1st argument of each callback
** invocation. ^If the callback pointer to sqlite3_exec() or sqlite3_exec_b()
** is NULL, then no callback is ever invoked and result rows are ignored.
**
** ^If an error occurs while evaluating the SQL statements passed into
** sqlite3_exec(), then execution of the current statement stops and
@@ -373,7 +388,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
** NULL before returning.
**
** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
** ^If an sqlite3_exec() or sqlite3_exec_b() callback returns non-zero, the
** routine returns SQLITE_ABORT without invoking the callback again and
** without running any subsequent SQL statements.
**
@@ -387,20 +402,26 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** entry represents the name of corresponding result column as obtained
** from [sqlite3_column_name()].
**
** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
** to an empty string, or a pointer that contains only whitespace and/or
** SQL comments, then no SQL statements are evaluated and the database
** is not changed.
** ^The 1st argument to the sqlite3_exec_b() callback block is a prepared
** statement object stopped at the current result row. The
** [column access functions] may be used to extract the row's values.
**
** ^If the 2nd parameter to sqlite3_exec() or sqlite3_exec_b() is a NULL
** pointer, a pointer to an empty string, or a pointer that contains only
** whitespace and/or SQL comments, then no SQL statements are evaluated and
** the database is not changed.
**
** Restrictions:
**
** <ul>
** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
** or sqlite3_exec_b() is a valid and open [database connection].
** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** the 1st parameter to sqlite3_exec() or sqlite3_exec_b() while the
** routine is running.
** <li> The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** the 2nd parameter of sqlite3_exec() or sqlite3_exec_b() while the
** routine is running.
** </ul>
*/
int sqlite3_exec(
@@ -410,6 +431,13 @@ int sqlite3_exec(
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
#if __has_extension(blocks)
int sqlite3_exec_b(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
SQLITE_NOESCAPE int (^callback)(sqlite3_stmt*) /* Callback block */
);
#endif
/*
** CAPI3REF: Result Codes
+11
View File
@@ -166,6 +166,17 @@
*/
#include "sqlite3.h"
/*
** SQLITE_HAS_BLOCKS controls block API availability
*/
#ifndef SQLITE_HAS_BLOCKS
# if __has_extension(blocks)
# define SQLITE_HAS_BLOCKS 1
# else
# define SQLITE_HAS_BLOCKS 0
# endif
#endif
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build