Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merged in trunk for SSL improvements and deployment to test server. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | chat-user-last-seen |
| Files: | files | file ages | folders |
| SHA3-256: |
422323618ecbba813c0d04882730d461 |
| User & Date: | stephan 2021-06-15 03:00:33.890 |
Context
|
2021-06-15
| ||
| 14:24 | The SCRIPT argument to the test-th-eval command may now be a file name or a script string. (Edit: closing branch - we have yet to find a compelling use for this feature.) ... (Closed-Leaf check-in: 2ee8730870 user: stephan tags: chat-user-last-seen) | |
| 03:00 | Merged in trunk for SSL improvements and deployment to test server. ... (check-in: 422323618e user: stephan tags: chat-user-last-seen) | |
| 02:44 | xekri skin: recolor links in fossil-PopupWidget elements so that the links are visible. ... (check-in: d2c8ba0f66 user: stephan tags: trunk) | |
|
2021-06-14
| ||
| 13:48 | /chat: experimentally render a list of users ordered by most recent activity. Until/unless we can find a useful function for the list, though, it's really just a somewhat pretty screen space hog. ... (check-in: c7ee6f4ef1 user: stephan tags: chat-user-last-seen) | |
Changes
Changes to skins/xekri/css.txt.
| ︙ | ︙ | |||
1122 1123 1124 1125 1126 1127 1128 |
}
.fossil-PopupWidget,
.fossil-tooltip.help-buttonlet-content {
background-color: #111;
border: 1px solid rgba(255,255,255,0.5);
}
| > > > | | 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 |
}
.fossil-PopupWidget,
.fossil-tooltip.help-buttonlet-content {
background-color: #111;
border: 1px solid rgba(255,255,255,0.5);
}
.fossil-PopupWidget a,
.fossil-PopupWidget a:visited {
color: white;
}
div.forumSel {
background-color: #663399;
}
div.forumPostBody blockquote {
border-width: 1pt;
border-style: solid;
padding: 0 0.5em;
|
| ︙ | ︙ |
Changes to src/chat.js.
| ︙ | ︙ | |||
783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
const btnDeleteGlobal = D.button("Delete globally");
D.append(toolbar, btnDeleteGlobal);
btnDeleteGlobal.addEventListener('click', function(){
self.hide();
Chat.deleteMessage(eMsg);
});
}
}/*refresh()*/
});
f.popup.installHideHandlers();
f.popup.hide = function(){
delete this._eMsg;
D.clearElement(this.e);
return this.show(false);
| > > > > > > > > > > > > > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 |
const btnDeleteGlobal = D.button("Delete globally");
D.append(toolbar, btnDeleteGlobal);
btnDeleteGlobal.addEventListener('click', function(){
self.hide();
Chat.deleteMessage(eMsg);
});
}
if(eMsg.dataset.xfrom){
/* Add a link to the /timeline filtered on this user. */
const toolbar2 = D.addClass(D.div(), 'toolbar');
D.append(this.e, toolbar2);
const timelineLink = D.attr(
D.a(F.repoUrl('timeline',{
u: eMsg.dataset.xfrom,
y: 'a'
}), "User's Timeline"),
'target', '_blank'
);
D.append(toolbar2, timelineLink);
}
}/*refresh()*/
});
f.popup.installHideHandlers();
f.popup.hide = function(){
delete this._eMsg;
D.clearElement(this.e);
return this.show(false);
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
862 863 864 865 866 867 868 | db_find_and_open_repository(0,0); db_prepare(&err, "INSERT INTO repository.config(name) VALUES(NULL);"); db_exec(&err); } /* ** COMMAND: test-db-prepare | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 |
db_find_and_open_repository(0,0);
db_prepare(&err, "INSERT INTO repository.config(name) VALUES(NULL);");
db_exec(&err);
}
/*
** COMMAND: test-db-prepare
** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
**
** Options:
**
** --auth-report Enable the ticket report query authorizer.
** --auth-ticket Enable the ticket schema query authorizer.
**
** Invoke db_prepare() on the SQL input. Report any errors encountered.
** This command is used to verify error detection logic in the db_prepare()
** utility routine.
*/
void db_test_db_prepare(void){
const int fAuthReport = find_option("auth-report",0,0)!=0;
const int fAuthSchema = find_option("auth-ticket",0,0)!=0;
const int fAuth = fAuthReport + fAuthSchema;
char * zReportErr = 0; /* auth-report error string. */
int nSchemaErr = 0; /* Number of auth-ticket errors. */
Stmt err;
if(fAuth>1){
fossil_fatal("Only one of --auth-report or --auth-ticket "
"may be used.");
}
db_find_and_open_repository(0,0);
verify_all_options();
if( g.argc!=3 ) usage("?OPTIONS? SQL");
if(fAuthReport){
report_restrict_sql(&zReportErr);
}else if(fAuthSchema){
ticket_restrict_sql(&nSchemaErr);
}
db_prepare(&err, "%s", g.argv[2]/*safe-for-%s*/);
db_finalize(&err);
if(fAuthReport){
report_unrestrict_sql();
if(zReportErr){
fossil_warning("Report authorizer error: %s\n", zReportErr);
fossil_free(zReportErr);
}
}else if(fAuthSchema){
ticket_unrestrict_sql();
if(nSchemaErr){
fossil_warning("Ticket schema authorizer error count: %d\n",
nSchemaErr);
}
}
}
/*
** Print the output of one or more SQL queries on standard output.
** This routine is used for debugging purposes only.
*/
int db_debug(const char *zSql, ...){
|
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 |
border-radius: 0.25em;
background-color: rgba(20, 20, 20, 1)
/* problem: if we inherit the color it may either be
transparent or inherit translucency via the
skin, leaving it unreadable. Since we set the bg
color we must also set the fg color. */;
color: rgba(235, 235, 235, 0.9);
}
.fossil-toast-message.error,
.fossil-toast-message.warning {
background: yellow;
}
.fossil-toast-message.error {
font-weight: bold;
| > > > > | 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 |
border-radius: 0.25em;
background-color: rgba(20, 20, 20, 1)
/* problem: if we inherit the color it may either be
transparent or inherit translucency via the
skin, leaving it unreadable. Since we set the bg
color we must also set the fg color. */;
color: rgba(235, 235, 235, 0.9);
}
.fossil-PopupWidget a,
.fossil-PopupWidget a:visited {
color: initial;
}
.fossil-toast-message.error,
.fossil-toast-message.warning {
background: yellow;
}
.fossil-toast-message.error {
font-weight: bold;
|
| ︙ | ︙ |
Changes to src/http_ssl.c.
| ︙ | ︙ | |||
250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
** g.url.name Name of the proxy server, if proxying.
** pUrlData->port TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int ssl_open(UrlData *pUrlData){
X509 *cert;
ssl_global_init();
if( pUrlData->useProxy ){
int rc;
char *connStr = mprintf("%s:%d", g.url.name, pUrlData->port);
BIO *sBio = BIO_new_connect(connStr);
free(connStr);
| > | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
** g.url.name Name of the proxy server, if proxying.
** pUrlData->port TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int ssl_open(UrlData *pUrlData){
X509 *cert;
const char *zRemoteHost;
ssl_global_init();
if( pUrlData->useProxy ){
int rc;
char *connStr = mprintf("%s:%d", g.url.name, pUrlData->port);
BIO *sBio = BIO_new_connect(connStr);
free(connStr);
|
| ︙ | ︙ | |||
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
return 1;
}
pUrlData->path = pUrlData->proxyUrlPath;
iBio = BIO_new_ssl(sslCtx, 1);
BIO_push(iBio, sBio);
}else{
iBio = BIO_new_ssl_connect(sslCtx);
}
if( iBio==NULL ) {
ssl_set_errmsg("SSL: cannot open SSL (%s)",
ERR_reason_error_string(ERR_get_error()));
return 1;
}
BIO_get_ssl(iBio, &ssl);
#if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT)
| > > | < < > > > > > > > > > > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
return 1;
}
pUrlData->path = pUrlData->proxyUrlPath;
iBio = BIO_new_ssl(sslCtx, 1);
BIO_push(iBio, sBio);
zRemoteHost = pUrlData->hostname;
}else{
iBio = BIO_new_ssl_connect(sslCtx);
zRemoteHost = pUrlData->name;
}
if( iBio==NULL ) {
ssl_set_errmsg("SSL: cannot open SSL (%s)",
ERR_reason_error_string(ERR_get_error()));
return 1;
}
BIO_get_ssl(iBio, &ssl);
#if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT)
if( !SSL_set_tlsext_host_name(ssl, zRemoteHost)){
fossil_warning("WARNING: failed to set server name indication (SNI), "
"continuing without it.\n");
}
#endif
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
#if OPENSSL_VERSION_NUMBER >= 0x010002000
if( !sslNoCertVerify ){
X509_VERIFY_PARAM *param = 0;
param = SSL_get0_param(ssl);
if( !X509_VERIFY_PARAM_set1_host(param, zRemoteHost, strlen(zRemoteHost)) ){
fossil_fatal("failed to set hostname.");
}
/* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */
}
#endif
if( !pUrlData->useProxy ){
char *connStr = mprintf("%s:%d", pUrlData->name, pUrlData->port);
BIO_set_conn_hostname(iBio, connStr);
free(connStr);
if( BIO_do_connect(iBio)<=0 ){
ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)",
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /*********************************************************************/ /* ** This is the SQLite authorizer callback used to make sure that the ** SQL statements entered by users do not try to do anything untoward. ** If anything suspicious is tried, set *(char**)pError to an error ** message obtained from malloc. */ static int report_query_authorizer( void *pError, int code, const char *zArg1, const char *zArg2, const char *zArg3, | > > > | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | /*********************************************************************/ /* ** This is the SQLite authorizer callback used to make sure that the ** SQL statements entered by users do not try to do anything untoward. ** If anything suspicious is tried, set *(char**)pError to an error ** message obtained from malloc. ** ** Use the "fossil test-db-prepare --auth-report SQL" command to perform ** manual testing of this authorizer. */ static int report_query_authorizer( void *pError, int code, const char *zArg1, const char *zArg2, const char *zArg3, |
| ︙ | ︙ | |||
238 239 240 241 242 243 244 |
break;
}
}
return rc;
}
/*
| | > | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
break;
}
}
return rc;
}
/*
** Activate the ticket report query authorizer. Must be followed by an
** eventual call to report_unrestrict_sql().
*/
void report_restrict_sql(char **pzErr){
db_set_authorizer(report_query_authorizer,(void*)pzErr,"Ticket-Report");
sqlite3_limit(g.db, SQLITE_LIMIT_VDBE_OP, 10000);
}
void report_unrestrict_sql(void){
db_clear_authorizer();
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
6202 6203 6204 6205 6206 6207 6208 |
}else{
j++;
}
}
}
if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
if( hit ) re_add_state(pNext, x+n);
| | | 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 |
}else{
j++;
}
}
}
if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
if( hit ) re_add_state(pNext, x+n);
break;
}
}
}
}
for(i=0; i<pNext->nState; i++){
if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
}
|
| ︙ | ︙ | |||
6363 6364 6365 6366 6367 6368 6369 |
int iStart;
unsigned c;
const char *zErr;
while( (c = p->xNextChar(&p->sIn))!=0 ){
iStart = p->nState;
switch( c ){
case '|':
| | | | 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 |
int iStart;
unsigned c;
const char *zErr;
while( (c = p->xNextChar(&p->sIn))!=0 ){
iStart = p->nState;
switch( c ){
case '|':
case '$':
case ')': {
p->sIn.i--;
return 0;
}
case '(': {
zErr = re_subcompile_re(p);
if( zErr ) return zErr;
if( rePeek(p)!=')' ) return "unmatched '('";
p->sIn.i++;
break;
}
case '.': {
if( rePeek(p)=='*' ){
re_append(p, RE_OP_ANYSTAR, 0);
p->sIn.i++;
}else{
re_append(p, RE_OP_ANY, 0);
}
break;
}
case '*': {
if( iPrev<0 ) return "'*' without operand";
re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1);
|
| ︙ | ︙ | |||
6588 6589 6590 6591 6592 6593 6594 | ** pattern and the second argument is the string. So, the SQL statements: ** ** A REGEXP B ** ** is implemented as regexp(B,A). */ static void re_sql_func( | | | | 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 |
** pattern and the second argument is the string. So, the SQL statements:
**
** A REGEXP B
**
** is implemented as regexp(B,A).
*/
static void re_sql_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
ReCompiled *pRe; /* Compiled regular expression */
const char *zPattern; /* The regular expression */
const unsigned char *zStr;/* String being searched */
const char *zErr; /* Compile error message */
int setAux = 0; /* True to invoke sqlite3_set_auxdata() */
|
| ︙ | ︙ | |||
14813 14814 14815 14816 14817 14818 14819 | " -C DIR, --directory DIR Read/extract files from directory DIR", " -n, --dryrun Show the SQL that would have occurred", " Examples:", " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar", " .ar -tf ARCHIVE # List members of ARCHIVE", " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE", " See also:", | | | 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 | " -C DIR, --directory DIR Read/extract files from directory DIR", " -n, --dryrun Show the SQL that would have occurred", " Examples:", " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar", " .ar -tf ARCHIVE # List members of ARCHIVE", " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE", " See also:", " http://sqlite.org/cli.html#sqlite_archive_support", #endif #ifndef SQLITE_OMIT_AUTHORIZATION ".auth ON|OFF Show authorizer callbacks", #endif ".backup ?DB? FILE Backup DB (default \"main\") to FILE", " --append Use the appendvfs", " --async Write to FILE without journal and fsync()", |
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
1203 1204 1205 1206 1207 1208 1209 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.36.0" #define SQLITE_VERSION_NUMBER 3036000 | | | 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.36.0" #define SQLITE_VERSION_NUMBER 3036000 #define SQLITE_SOURCE_ID "2021-06-14 20:41:20 e5a5acd6006133c5da4a7dd79726dbaa41c0d60ebeda890f848a6aafe5f9ef70" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 | /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif /* ** The default size of a disk sector */ #ifndef SQLITE_DEFAULT_SECTOR_SIZE # define SQLITE_DEFAULT_SECTOR_SIZE 4096 #endif | > > > > > > | 16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 16570 16571 16572 16573 16574 16575 | /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif /* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h */ #ifndef SQLITE_MAX_PATHLEN # define SQLITE_MAX_PATHLEN FILENAME_MAX #endif /* ** The default size of a disk sector */ #ifndef SQLITE_DEFAULT_SECTOR_SIZE # define SQLITE_DEFAULT_SECTOR_SIZE 4096 #endif |
| ︙ | ︙ | |||
18793 18794 18795 18796 18797 18798 18799 18800 18801 18802 18803 18804 18805 18806 | #define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** ** SRT_Union Store results as a key in a temporary index | > | 18799 18800 18801 18802 18803 18804 18805 18806 18807 18808 18809 18810 18811 18812 18813 | #define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** ** SRT_Union Store results as a key in a temporary index |
| ︙ | ︙ | |||
20156 20157 20158 20159 20160 20161 20162 20163 20164 20165 20166 20167 20168 20169 | SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, | > | 20163 20164 20165 20166 20167 20168 20169 20170 20171 20172 20173 20174 20175 20176 20177 | SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, |
| ︙ | ︙ | |||
20566 20567 20568 20569 20570 20571 20572 | SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); | | | 20574 20575 20576 20577 20578 20579 20580 20581 20582 20583 20584 20585 20586 20587 20588 | SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); #else # define sqlite3CteNew(P,T,E,S) ((void*)0) # define sqlite3CteDelete(D,C) # define sqlite3CteWithAdd(P,W,C) ((void*)0) # define sqlite3WithDelete(x,y) # define sqlite3WithPush(x,y,z) #endif |
| ︙ | ︙ | |||
21668 21669 21670 21671 21672 21673 21674 | SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); | | | 21676 21677 21678 21679 21680 21681 21682 21683 21684 21685 21686 21687 21688 21689 21690 | SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 #else SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); |
| ︙ | ︙ | |||
23665 23666 23667 23668 23669 23670 23671 23672 23673 23674 23675 23676 23677 23678 |
){
DO_OS_MALLOC_TEST(0);
zPathOut[0] = 0;
return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
return pVfs->xDlOpen(pVfs, zPath);
}
SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
pVfs->xDlError(pVfs, nByte, zBufOut);
}
SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
return pVfs->xDlSym(pVfs, pHdle, zSym);
| > > | 23673 23674 23675 23676 23677 23678 23679 23680 23681 23682 23683 23684 23685 23686 23687 23688 |
){
DO_OS_MALLOC_TEST(0);
zPathOut[0] = 0;
return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
assert( zPath!=0 );
assert( strlen(zPath)<=SQLITE_MAX_PATHLEN ); /* tag-20210611-1 */
return pVfs->xDlOpen(pVfs, zPath);
}
SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
pVfs->xDlError(pVfs, nByte, zBufOut);
}
SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
return pVfs->xDlSym(pVfs, pHdle, zSym);
|
| ︙ | ︙ | |||
66963 66964 66965 66966 66967 66968 66969 |
assert( cbrk+size<=usableSize && cbrk>=iCellStart );
testcase( cbrk+size==usableSize );
testcase( pc+size==usableSize );
put2byte(pAddr, cbrk);
if( temp==0 ){
if( cbrk==pc ) continue;
temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
| | | 66973 66974 66975 66976 66977 66978 66979 66980 66981 66982 66983 66984 66985 66986 66987 |
assert( cbrk+size<=usableSize && cbrk>=iCellStart );
testcase( cbrk+size==usableSize );
testcase( pc+size==usableSize );
put2byte(pAddr, cbrk);
if( temp==0 ){
if( cbrk==pc ) continue;
temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart);
src = temp;
}
memcpy(&data[cbrk], &src[pc], size);
}
data[hdr+7] = 0;
defragment_out:
|
| ︙ | ︙ | |||
78045 78046 78047 78048 78049 78050 78051 | ** stored without allocating memory, then it is. If a memory allocation ** is required to store the string, then value of pMem is unchanged. In ** either case, SQLITE_TOOBIG is returned. */ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ | | | | 78055 78056 78057 78058 78059 78060 78061 78062 78063 78064 78065 78066 78067 78068 78069 78070 78071 78072 78073 |
** stored without allocating memory, then it is. If a memory allocation
** is required to store the string, then value of pMem is unchanged. In
** either case, SQLITE_TOOBIG is returned.
*/
SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
Mem *pMem, /* Memory cell to set to string value */
const char *z, /* String pointer */
i64 n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
i64 nByte = n; /* New value for pMem->n */
int iLimit; /* Maximum allowed string or blob size */
u16 flags = 0; /* New value for pMem->flags */
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
|
| ︙ | ︙ | |||
78071 78072 78073 78074 78075 78076 78077 |
}else{
iLimit = SQLITE_MAX_LENGTH;
}
flags = (enc==0?MEM_Blob:MEM_Str);
if( nByte<0 ){
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
| | | | 78081 78082 78083 78084 78085 78086 78087 78088 78089 78090 78091 78092 78093 78094 78095 78096 78097 78098 78099 78100 78101 78102 78103 78104 78105 78106 78107 |
}else{
iLimit = SQLITE_MAX_LENGTH;
}
flags = (enc==0?MEM_Blob:MEM_Str);
if( nByte<0 ){
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
nByte = strlen(z);
}else{
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
}
flags |= MEM_Term;
}
/* The following block sets the new values of Mem.z and Mem.xDel. It
** also sets a flag in local variable "flags" to indicate the memory
** management (one of MEM_Dyn or MEM_Static).
*/
if( xDel==SQLITE_TRANSIENT ){
i64 nAlloc = nByte;
if( flags&MEM_Term ){
nAlloc += (enc==SQLITE_UTF8?1:2);
}
if( nByte>iLimit ){
return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
}
testcase( nAlloc==0 );
|
| ︙ | ︙ | |||
78109 78110 78111 78112 78113 78114 78115 |
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}else{
pMem->xDel = xDel;
flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
}
}
| | | | 78119 78120 78121 78122 78123 78124 78125 78126 78127 78128 78129 78130 78131 78132 78133 78134 78135 78136 78137 78138 78139 78140 78141 78142 78143 78144 78145 78146 78147 78148 78149 78150 78151 78152 78153 |
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}else{
pMem->xDel = xDel;
flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
}
}
pMem->n = (int)(nByte & 0x7fffffff);
pMem->flags = flags;
if( enc ){
pMem->enc = enc;
#ifdef SQLITE_ENABLE_SESSION
}else if( pMem->db==0 ){
pMem->enc = SQLITE_UTF8;
#endif
}else{
assert( pMem->db!=0 );
pMem->enc = ENC(pMem->db);
}
#ifndef SQLITE_OMIT_UTF16
if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
return SQLITE_NOMEM_BKPT;
}
#endif
if( nByte>iLimit ){
return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
}
return SQLITE_OK;
}
/*
** Move data out of a btree key or data field and into a Mem structure.
|
| ︙ | ︙ | |||
84525 84526 84527 84528 84529 84530 84531 |
if( xDel==0 ){
/* noop */
}else if( xDel==SQLITE_TRANSIENT ){
/* noop */
}else{
xDel((void*)p);
}
| | | 84535 84536 84537 84538 84539 84540 84541 84542 84543 84544 84545 84546 84547 84548 84549 |
if( xDel==0 ){
/* noop */
}else if( xDel==SQLITE_TRANSIENT ){
/* noop */
}else{
xDel((void*)p);
}
sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
SQLITE_API void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
|
| ︙ | ︙ | |||
85507 85508 85509 85510 85511 85512 85513 | /* ** Bind a text or BLOB value. */ static int bindText( sqlite3_stmt *pStmt, /* The statement to bind against */ int i, /* Index of the parameter to bind */ const void *zData, /* Pointer to the data to be bound */ | | | 85517 85518 85519 85520 85521 85522 85523 85524 85525 85526 85527 85528 85529 85530 85531 |
/*
** Bind a text or BLOB value.
*/
static int bindText(
sqlite3_stmt *pStmt, /* The statement to bind against */
int i, /* Index of the parameter to bind */
const void *zData, /* Pointer to the data to be bound */
i64 nData, /* Number of bytes of data to be bound */
void (*xDel)(void*), /* Destructor for the data */
u8 encoding /* Encoding for the data */
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
int rc;
|
| ︙ | ︙ | |||
85559 85560 85561 85562 85563 85564 85565 |
sqlite3_stmt *pStmt,
int i,
const void *zData,
sqlite3_uint64 nData,
void (*xDel)(void*)
){
assert( xDel!=SQLITE_DYNAMIC );
| < < < | < | 85569 85570 85571 85572 85573 85574 85575 85576 85577 85578 85579 85580 85581 85582 85583 |
sqlite3_stmt *pStmt,
int i,
const void *zData,
sqlite3_uint64 nData,
void (*xDel)(void*)
){
assert( xDel!=SQLITE_DYNAMIC );
return bindText(pStmt, i, zData, nData, xDel, 0);
}
SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
|
| ︙ | ︙ | |||
85633 85634 85635 85636 85637 85638 85639 |
int i,
const char *zData,
sqlite3_uint64 nData,
void (*xDel)(void*),
unsigned char enc
){
assert( xDel!=SQLITE_DYNAMIC );
| < < < | | < | 85639 85640 85641 85642 85643 85644 85645 85646 85647 85648 85649 85650 85651 85652 85653 85654 |
int i,
const char *zData,
sqlite3_uint64 nData,
void (*xDel)(void*),
unsigned char enc
){
assert( xDel!=SQLITE_DYNAMIC );
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
return bindText(pStmt, i, zData, nData, xDel, enc);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
|
| ︙ | ︙ | |||
90955 90956 90957 90958 90959 90960 90961 | UnpackedRecord r; assert( pOp[1].opcode==OP_SeekGE ); /* pOp->p2 points to the first instruction past the OP_IdxGT that ** follows the OP_SeekGE. */ assert( pOp->p2>=(int)(pOp-aOp)+2 ); | | > | 90957 90958 90959 90960 90961 90962 90963 90964 90965 90966 90967 90968 90969 90970 90971 90972 | UnpackedRecord r; assert( pOp[1].opcode==OP_SeekGE ); /* pOp->p2 points to the first instruction past the OP_IdxGT that ** follows the OP_SeekGE. */ assert( pOp->p2>=(int)(pOp-aOp)+2 ); assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); assert( pOp->p1>0 ); pC = p->apCsr[pOp[1].p1]; assert( pC!=0 ); |
| ︙ | ︙ | |||
92845 92846 92847 92848 92849 92850 92851 |
for(iDb=0; iDb<db->nDb; iDb++){
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
}
#endif
iDb = pOp->p1;
assert( iDb>=0 && iDb<db->nDb );
| | > > | 92848 92849 92850 92851 92852 92853 92854 92855 92856 92857 92858 92859 92860 92861 92862 92863 92864 |
for(iDb=0; iDb<db->nDb; iDb++){
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
}
#endif
iDb = pOp->p1;
assert( iDb>=0 && iDb<db->nDb );
assert( DbHasProperty(db, iDb, DB_SchemaLoaded)
|| db->mallocFailed
|| (CORRUPT_DB && (db->flags & SQLITE_NoSchemaError)!=0) );
#ifndef SQLITE_OMIT_ALTERTABLE
if( pOp->p4.z==0 ){
sqlite3SchemaClear(db->aDb[iDb].pSchema);
db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5);
db->mDbFlags |= DBFLAG_SchemaChange;
|
| ︙ | ︙ | |||
102620 102621 102622 102623 102624 102625 102626 | /* ** Create and return a deep copy of the object passed as the second ** argument. If an OOM condition is encountered, NULL is returned ** and the db->mallocFailed flag set. */ #ifndef SQLITE_OMIT_CTE | | | | 102625 102626 102627 102628 102629 102630 102631 102632 102633 102634 102635 102636 102637 102638 102639 102640 102641 102642 102643 102644 102645 102646 102647 102648 102649 102650 102651 102652 102653 102654 102655 102656 102657 |
/*
** Create and return a deep copy of the object passed as the second
** argument. If an OOM condition is encountered, NULL is returned
** and the db->mallocFailed flag set.
*/
#ifndef SQLITE_OMIT_CTE
SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){
With *pRet = 0;
if( p ){
sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
pRet = sqlite3DbMallocZero(db, nByte);
if( pRet ){
int i;
pRet->nCte = p->nCte;
for(i=0; i<p->nCte; i++){
pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName);
}
}
}
return pRet;
}
#else
# define sqlite3WithDup(x,y) 0
#endif
#ifndef SQLITE_OMIT_WINDOWFUNC
/*
** The gatherSelectWindows() procedure and its helper routine
** gatherSelectWindowsCallback() are used to scan all the expressions
** an a newly duplicated SELECT statement and gather all of the Window
|
| ︙ | ︙ | |||
102842 102843 102844 102845 102846 102847 102848 |
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
| | | 102847 102848 102849 102850 102851 102852 102853 102854 102855 102856 102857 102858 102859 102860 102861 |
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = sqlite3WithDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
#endif
pNew->selId = p->selId;
if( db->mallocFailed ){
|
| ︙ | ︙ | |||
108182 108183 108184 108185 108186 108187 108188 108189 108190 108191 108192 108193 |
/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/
static void renameWalkWith(Walker *pWalker, Select *pSelect){
With *pWith = pSelect->pWith;
if( pWith ){
int i;
for(i=0; i<pWith->nCte; i++){
Select *p = pWith->a[i].pSelect;
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
| > > > > > > > > > > > > | | | > > > | 108187 108188 108189 108190 108191 108192 108193 108194 108195 108196 108197 108198 108199 108200 108201 108202 108203 108204 108205 108206 108207 108208 108209 108210 108211 108212 108213 108214 108215 108216 108217 108218 108219 108220 108221 108222 108223 108224 |
/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/
static void renameWalkWith(Walker *pWalker, Select *pSelect){
With *pWith = pSelect->pWith;
if( pWith ){
Parse *pParse = pWalker->pParse;
int i;
With *pCopy = 0;
assert( pWith->nCte>0 );
if( (pWith->a[0].pSelect->selFlags & SF_Expanded)==0 ){
/* Push a copy of the With object onto the with-stack. We use a copy
** here as the original will be expanded and resolved (flags SF_Expanded
** and SF_Resolved) below. And the parser code that uses the with-stack
** fails if the Select objects on it have already been expanded and
** resolved. */
pCopy = sqlite3WithDup(pParse->db, pWith);
pCopy = sqlite3WithPush(pParse, pCopy, 1);
}
for(i=0; i<pWith->nCte; i++){
Select *p = pWith->a[i].pSelect;
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC);
sqlite3WalkSelect(pWalker, p);
sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols);
}
if( pCopy && pParse->pWith==pCopy ){
pParse->pWith = pCopy->pOuter;
}
}
}
/*
** Unmap all tokens in the IdList object passed as the second argument.
*/
|
| ︙ | ︙ | |||
108217 108218 108219 108220 108221 108222 108223 |
/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( pParse->nErr ) return WRC_Abort;
| > > > | > | 108237 108238 108239 108240 108241 108242 108243 108244 108245 108246 108247 108248 108249 108250 108251 108252 108253 108254 108255 |
/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( pParse->nErr ) return WRC_Abort;
if( p->selFlags & (SF_View|SF_CopyCte) ){
testcase( pSelect->selFlags & SF_View );
testcase( pSelect->selFlags & SF_CopyCte );
return WRC_Prune;
}
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
}
}
|
| ︙ | ︙ | |||
108325 108326 108327 108328 108329 108330 108331 |
/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
| > > > | > | 108349 108350 108351 108352 108353 108354 108355 108356 108357 108358 108359 108360 108361 108362 108363 108364 108365 108366 108367 |
/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
if( p->selFlags & (SF_View|SF_CopyCte) ){
testcase( pSelect->selFlags & SF_View );
testcase( pSelect->selFlags & SF_CopyCte );
return WRC_Prune;
}
renameWalkWith(pWalker, p);
return WRC_Continue;
}
/*
** This is a Walker expression callback.
**
|
| ︙ | ︙ | |||
108961 108962 108963 108964 108965 108966 108967 |
/*
** Walker select callback used by "RENAME TABLE".
*/
static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
| | > > > > | 108989 108990 108991 108992 108993 108994 108995 108996 108997 108998 108999 109000 109001 109002 109003 109004 109005 109006 109007 |
/*
** Walker select callback used by "RENAME TABLE".
*/
static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
if( pSelect->selFlags & (SF_View|SF_CopyCte) ){
testcase( pSelect->selFlags & SF_View );
testcase( pSelect->selFlags & SF_CopyCte );
return WRC_Prune;
}
if( NEVER(pSrc==0) ){
assert( pWalker->pParse->db->mallocFailed );
return WRC_Abort;
}
for(i=0; i<pSrc->nSrc; i++){
SrcItem *pItem = &pSrc->a[i];
if( pItem->pTab==p->pTab ){
|
| ︙ | ︙ | |||
116703 116704 116705 116706 116707 116708 116709 |
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
}
| | | 116735 116736 116737 116738 116739 116740 116741 116742 116743 116744 116745 116746 116747 116748 116749 |
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
}
if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX;
if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
goto exit_drop_index;
}
}
#endif
/* Generate code to remove the index and from the schema table */
|
| ︙ | ︙ | |||
119235 119236 119237 119238 119239 119240 119241 |
&& pPrior->aiColumn[j]==pIdx->aiColumn[j]
&& pPrior->aiColumn[j]!=XN_EXPR
){
/* This column was already computed by the previous index */
continue;
}
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
| > | | | | | | | > | 119267 119268 119269 119270 119271 119272 119273 119274 119275 119276 119277 119278 119279 119280 119281 119282 119283 119284 119285 119286 119287 119288 119289 |
&& pPrior->aiColumn[j]==pIdx->aiColumn[j]
&& pPrior->aiColumn[j]!=XN_EXPR
){
/* This column was already computed by the previous index */
continue;
}
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
if( pIdx->aiColumn[j]>=0 ){
/* If the column affinity is REAL but the number is an integer, then it
** might be stored in the table as an integer (using a compact
** representation) then converted to REAL by an OP_RealAffinity opcode.
** But we are getting ready to store this value back into an index, where
** it should be converted by to INTEGER again. So omit the
** OP_RealAffinity opcode if it is present */
sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
}
}
if( regOut ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
}
sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
}
|
| ︙ | ︙ | |||
127399 127400 127401 127402 127403 127404 127405 | sqlite3_vfs *pVfs = db->pVfs; void *handle; sqlite3_loadext_entry xInit; char *zErrmsg = 0; const char *zEntry; char *zAltEntry = 0; void **aHandle; | | | 127433 127434 127435 127436 127437 127438 127439 127440 127441 127442 127443 127444 127445 127446 127447 |
sqlite3_vfs *pVfs = db->pVfs;
void *handle;
sqlite3_loadext_entry xInit;
char *zErrmsg = 0;
const char *zEntry;
char *zAltEntry = 0;
void **aHandle;
u64 nMsg = strlen(zFile);
int ii;
int rc;
/* Shared library endings to try if zFile cannot be loaded as written */
static const char *azEndings[] = {
#if SQLITE_OS_WIN
"dll"
|
| ︙ | ︙ | |||
127433 127434 127435 127436 127437 127438 127439 127440 127441 127442 127443 127444 127445 127446 127447 127448 |
*pzErrMsg = sqlite3_mprintf("not authorized");
}
return SQLITE_ERROR;
}
zEntry = zProc ? zProc : "sqlite3_extension_init";
handle = sqlite3OsDlOpen(pVfs, zFile);
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
| > > > > > > | < < < < < < < < < < | 127467 127468 127469 127470 127471 127472 127473 127474 127475 127476 127477 127478 127479 127480 127481 127482 127483 127484 127485 127486 127487 127488 127489 127490 127491 127492 127493 127494 127495 127496 |
*pzErrMsg = sqlite3_mprintf("not authorized");
}
return SQLITE_ERROR;
}
zEntry = zProc ? zProc : "sqlite3_extension_init";
/* tag-20210611-1. Some dlopen() implementations will segfault if given
** an oversize filename. Most filesystems have a pathname limit of 4K,
** so limit the extension filename length to about twice that.
** https://sqlite.org/forum/forumpost/08a0d6d9bf */
if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found;
handle = sqlite3OsDlOpen(pVfs, zFile);
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
if( handle==0 ) goto extension_not_found;
xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
/* If no entry point was specified and the default legacy
** entry point name "sqlite3_extension_init" was not found, then
** construct an entry point name "sqlite3_X_init" where the X is
** replaced by the lowercase value of every ASCII alphabetic
** character in the filename after the last "/" upto the first ".",
|
| ︙ | ︙ | |||
127489 127490 127491 127492 127493 127494 127495 |
}
memcpy(zAltEntry+iEntry, "_init", 6);
zEntry = zAltEntry;
xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
| | > | | 127519 127520 127521 127522 127523 127524 127525 127526 127527 127528 127529 127530 127531 127532 127533 127534 127535 127536 127537 |
}
memcpy(zAltEntry+iEntry, "_init", 6);
zEntry = zAltEntry;
xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
nMsg += strlen(zEntry) + 300;
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */
sqlite3_snprintf((int)nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zEntry, zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
}
sqlite3OsDlClose(pVfs, handle);
sqlite3_free(zAltEntry);
return SQLITE_ERROR;
|
| ︙ | ︙ | |||
127526 127527 127528 127529 127530 127531 127532 127533 127534 127535 127536 127537 127538 127539 |
memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
}
sqlite3DbFree(db, db->aExtension);
db->aExtension = aHandle;
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
char **pzErrMsg /* Put error message here if not 0 */
){
| > > > > > > > > > > > > > | 127557 127558 127559 127560 127561 127562 127563 127564 127565 127566 127567 127568 127569 127570 127571 127572 127573 127574 127575 127576 127577 127578 127579 127580 127581 127582 127583 |
memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
}
sqlite3DbFree(db, db->aExtension);
db->aExtension = aHandle;
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
extension_not_found:
if( pzErrMsg ){
nMsg += 300;
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */
sqlite3_snprintf((int)nMsg, zErrmsg,
"unable to open shared library [%.*s]", SQLITE_MAX_PATHLEN, zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
}
return SQLITE_ERROR;
}
SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
char **pzErrMsg /* Put error message here if not 0 */
){
|
| ︙ | ︙ | |||
131366 131367 131368 131369 131370 131371 131372 131373 131374 131375 131376 131377 131378 131379 131380 131381 131382 |
sqlite3DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}else
if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
/* Hack: If the SQLITE_NoSchemaError flag is set, then consider
** the schema loaded, even if errors (other than OOM) occurred. In
** this situation the current sqlite3_prepare() operation will fail,
** but the following one will attempt to compile the supplied statement
** against whatever subset of the schema was loaded before the error
| > > | 131410 131411 131412 131413 131414 131415 131416 131417 131418 131419 131420 131421 131422 131423 131424 131425 131426 131427 131428 |
sqlite3DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
assert( pDb == &(db->aDb[iDb]) );
if( db->mallocFailed ){
rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
pDb = &db->aDb[iDb];
}else
if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
/* Hack: If the SQLITE_NoSchemaError flag is set, then consider
** the schema loaded, even if errors (other than OOM) occurred. In
** this situation the current sqlite3_prepare() operation will fail,
** but the following one will attempt to compile the supplied statement
** against whatever subset of the schema was loaded before the error
|
| ︙ | ︙ | |||
136424 136425 136426 136427 136428 136429 136430 136431 136432 136433 136434 136435 136436 136437 |
/*
** A structure to keep track of all of the column values that are fixed to
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
*/
typedef struct WhereConst WhereConst;
struct WhereConst {
Parse *pParse; /* Parsing context */
int nConst; /* Number for COLUMN=CONSTANT terms */
int nChng; /* Number of times a constant is propagated */
int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */
Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
};
/*
| > | 136470 136471 136472 136473 136474 136475 136476 136477 136478 136479 136480 136481 136482 136483 136484 |
/*
** A structure to keep track of all of the column values that are fixed to
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
*/
typedef struct WhereConst WhereConst;
struct WhereConst {
Parse *pParse; /* Parsing context */
u8 *pOomFault; /* Pointer to pParse->db->mallocFailed */
int nConst; /* Number for COLUMN=CONSTANT terms */
int nChng; /* Number of times a constant is propagated */
int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */
Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
};
/*
|
| ︙ | ︙ | |||
136523 136524 136525 136526 136527 136528 136529 136530 136531 136532 136533 136534 136535 136536 136537 136538 136539 136540 136541 136542 136543 136544 136545 136546 136547 136548 136549 136550 136551 136552 136553 136554 136555 136556 |
*/
static int propagateConstantExprRewriteOne(
WhereConst *pConst,
Expr *pExpr,
int bIgnoreAffBlob
){
int i;
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
testcase( ExprHasProperty(pExpr, EP_FixedCol) );
testcase( ExprHasProperty(pExpr, EP_FromJoin) );
return WRC_Continue;
}
for(i=0; i<pConst->nConst; i++){
Expr *pColumn = pConst->apExpr[i*2];
if( pColumn==pExpr ) continue;
if( pColumn->iTable!=pExpr->iTable ) continue;
if( pColumn->iColumn!=pExpr->iColumn ) continue;
if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
break;
}
/* A match is found. Add the EP_FixedCol property */
pConst->nChng++;
ExprClearProperty(pExpr, EP_Leaf);
ExprSetProperty(pExpr, EP_FixedCol);
assert( pExpr->pLeft==0 );
pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0);
break;
}
return WRC_Prune;
}
/*
** This is a Walker expression callback. pExpr is a node from the WHERE
| > > | 136570 136571 136572 136573 136574 136575 136576 136577 136578 136579 136580 136581 136582 136583 136584 136585 136586 136587 136588 136589 136590 136591 136592 136593 136594 136595 136596 136597 136598 136599 136600 136601 136602 136603 136604 136605 |
*/
static int propagateConstantExprRewriteOne(
WhereConst *pConst,
Expr *pExpr,
int bIgnoreAffBlob
){
int i;
if( pConst->pOomFault[0] ) return WRC_Prune;
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
testcase( ExprHasProperty(pExpr, EP_FixedCol) );
testcase( ExprHasProperty(pExpr, EP_FromJoin) );
return WRC_Continue;
}
for(i=0; i<pConst->nConst; i++){
Expr *pColumn = pConst->apExpr[i*2];
if( pColumn==pExpr ) continue;
if( pColumn->iTable!=pExpr->iTable ) continue;
if( pColumn->iColumn!=pExpr->iColumn ) continue;
if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
break;
}
/* A match is found. Add the EP_FixedCol property */
pConst->nChng++;
ExprClearProperty(pExpr, EP_Leaf);
ExprSetProperty(pExpr, EP_FixedCol);
assert( pExpr->pLeft==0 );
pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0);
if( pConst->pParse->db->mallocFailed ) return WRC_Prune;
break;
}
return WRC_Prune;
}
/*
** This is a Walker expression callback. pExpr is a node from the WHERE
|
| ︙ | ︙ | |||
136575 136576 136577 136578 136579 136580 136581 136582 136583 136584 136585 136586 136587 136588 |
assert( TK_LT==TK_EQ+3 );
assert( TK_GE==TK_EQ+4 );
if( pConst->bHasAffBlob ){
if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE)
|| pExpr->op==TK_IS
){
propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0);
if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){
propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0);
}
}
}
return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob);
}
| > | 136624 136625 136626 136627 136628 136629 136630 136631 136632 136633 136634 136635 136636 136637 136638 |
assert( TK_LT==TK_EQ+3 );
assert( TK_GE==TK_EQ+4 );
if( pConst->bHasAffBlob ){
if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE)
|| pExpr->op==TK_IS
){
propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0);
if( pConst->pOomFault[0] ) return WRC_Prune;
if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){
propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0);
}
}
}
return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob);
}
|
| ︙ | ︙ | |||
136642 136643 136644 136645 136646 136647 136648 136649 136650 136651 136652 136653 136654 136655 |
Parse *pParse, /* The parsing context */
Select *p /* The query in which to propagate constants */
){
WhereConst x;
Walker w;
int nChng = 0;
x.pParse = pParse;
do{
x.nConst = 0;
x.nChng = 0;
x.apExpr = 0;
x.bHasAffBlob = 0;
findConstInWhere(&x, p->pWhere);
if( x.nConst ){
| > | 136692 136693 136694 136695 136696 136697 136698 136699 136700 136701 136702 136703 136704 136705 136706 |
Parse *pParse, /* The parsing context */
Select *p /* The query in which to propagate constants */
){
WhereConst x;
Walker w;
int nChng = 0;
x.pParse = pParse;
x.pOomFault = &pParse->db->mallocFailed;
do{
x.nConst = 0;
x.nChng = 0;
x.apExpr = 0;
x.bHasAffBlob = 0;
findConstInWhere(&x, p->pWhere);
if( x.nConst ){
|
| ︙ | ︙ | |||
137097 137098 137099 137100 137101 137102 137103 137104 | ** ** This routine pushes the WITH clause passed as the second argument ** onto the top of the stack. If argument bFree is true, then this ** WITH clause will never be popped from the stack but should instead ** be freed along with the Parse object. In other cases, when ** bFree==0, the With object will be freed along with the SELECT ** statement with which it is associated. */ | > > > > > > > | > > > > > > < < < < < | < > | 137148 137149 137150 137151 137152 137153 137154 137155 137156 137157 137158 137159 137160 137161 137162 137163 137164 137165 137166 137167 137168 137169 137170 137171 137172 137173 137174 137175 137176 137177 137178 137179 137180 137181 137182 137183 137184 |
**
** This routine pushes the WITH clause passed as the second argument
** onto the top of the stack. If argument bFree is true, then this
** WITH clause will never be popped from the stack but should instead
** be freed along with the Parse object. In other cases, when
** bFree==0, the With object will be freed along with the SELECT
** statement with which it is associated.
**
** This routine returns a copy of pWith. Or, if bFree is true and
** the pWith object is destroyed immediately due to an OOM condition,
** then this routine return NULL.
**
** If bFree is true, do not continue to use the pWith pointer after
** calling this routine, Instead, use only the return value.
*/
SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
if( pWith ){
if( bFree ){
pWith = (With*)sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3WithDelete,
pWith);
if( pWith==0 ) return 0;
}
if( pParse->nErr==0 ){
assert( pParse->pWith!=pWith );
pWith->pOuter = pParse->pWith;
pParse->pWith = pWith;
}
}
return pWith;
}
/*
** This function checks if argument pFrom refers to a CTE declared by
** a WITH clause on the stack currently maintained by the parser (on the
** pParse->pWith linked list). And if currently processing a CTE
** CTE expression, through routine checks to see if the reference is
|
| ︙ | ︙ | |||
137204 137205 137206 137207 137208 137209 137210 137211 137212 137213 137214 137215 137216 137217 |
pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
if( db->mallocFailed ) return 2;
assert( pFrom->pSelect );
pFrom->fg.isCte = 1;
pFrom->u2.pCteUse = pCteUse;
pCteUse->nUse++;
if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
pCteUse->eM10d = M10d_Yes;
}
| > | 137263 137264 137265 137266 137267 137268 137269 137270 137271 137272 137273 137274 137275 137276 137277 |
pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
if( db->mallocFailed ) return 2;
pFrom->pSelect->selFlags |= SF_CopyCte;
assert( pFrom->pSelect );
pFrom->fg.isCte = 1;
pFrom->u2.pCteUse = pCteUse;
pCteUse->nUse++;
if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
pCteUse->eM10d = M10d_Yes;
}
|
| ︙ | ︙ | |||
137472 137473 137474 137475 137476 137477 137478 137479 137480 137481 137482 137483 137484 137485 |
&& (db->flags & SQLITE_EnableView)==0
&& pTab->pSchema!=db->aDb[1].pSchema
){
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
pTab->zName);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab)
&& pFrom->fg.fromDDL
&& ALWAYS(pTab->pVTable!=0)
&& pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
){
sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
pTab->zName);
| > | 137532 137533 137534 137535 137536 137537 137538 137539 137540 137541 137542 137543 137544 137545 137546 |
&& (db->flags & SQLITE_EnableView)==0
&& pTab->pSchema!=db->aDb[1].pSchema
){
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
pTab->zName);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 );
if( IsVirtual(pTab)
&& pFrom->fg.fromDDL
&& ALWAYS(pTab->pVTable!=0)
&& pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
){
sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
pTab->zName);
|
| ︙ | ︙ | |||
183219 183220 183221 183222 183223 183224 183225 |
static int fts3PrefixCompress(
const char *zPrev, /* Buffer containing previous term */
int nPrev, /* Size of buffer zPrev in bytes */
const char *zNext, /* Buffer containing next term */
int nNext /* Size of buffer zNext in bytes */
){
int n;
| < | > | 183280 183281 183282 183283 183284 183285 183286 183287 183288 183289 183290 183291 183292 183293 183294 183295 |
static int fts3PrefixCompress(
const char *zPrev, /* Buffer containing previous term */
int nPrev, /* Size of buffer zPrev in bytes */
const char *zNext, /* Buffer containing next term */
int nNext /* Size of buffer zNext in bytes */
){
int n;
for(n=0; n<nPrev && n<nNext && zPrev[n]==zNext[n]; n++);
assert_fts3_nc( n<nNext );
return n;
}
/*
** Add term zTerm to the SegmentNode. It is guaranteed that zTerm is larger
** (according to memcmp) than the previous term.
*/
|
| ︙ | ︙ | |||
184219 184220 184221 184222 184223 184224 184225 |
}else{
if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB;
iDelta = (i64)((u64)iDocid - (u64)iPrev);
}
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
| | | 184280 184281 184282 184283 184284 184285 184286 184287 184288 184289 184290 184291 184292 184293 184294 |
}else{
if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB;
iDelta = (i64)((u64)iDocid - (u64)iPrev);
}
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
if( isFirst ){
char *a = &pCsr->aBuffer[nDoclist];
int nWrite;
nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
|
| ︙ | ︙ | |||
216162 216163 216164 216165 216166 216167 216168 216169 216170 216171 216172 216173 216174 216175 216176 216177 216178 216179 216180 216181 |
/* EOF */
*piOff = -1;
return 1;
}else{
i64 iOff = *piOff;
int iVal;
fts5FastGetVarint32(a, i, iVal);
if( iVal<=1 ){
if( iVal==0 ){
*pi = i;
return 0;
}
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
if( iVal<2 ){
/* This is a corrupt record. So stop parsing it here. */
*piOff = -1;
return 1;
}
| > < | > > > > | 216223 216224 216225 216226 216227 216228 216229 216230 216231 216232 216233 216234 216235 216236 216237 216238 216239 216240 216241 216242 216243 216244 216245 216246 216247 216248 216249 216250 216251 216252 216253 216254 216255 216256 |
/* EOF */
*piOff = -1;
return 1;
}else{
i64 iOff = *piOff;
int iVal;
fts5FastGetVarint32(a, i, iVal);
assert( iVal>=0 );
if( iVal<=1 ){
if( iVal==0 ){
*pi = i;
return 0;
}
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
if( iVal<2 ){
/* This is a corrupt record. So stop parsing it here. */
*piOff = -1;
return 1;
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
}else{
*piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF);
}
*pi = i;
assert( *piOff>=iOff );
return 0;
}
}
/*
** Advance the iterator object passed as the only argument. Return true
|
| ︙ | ︙ | |||
216216 216217 216218 216219 216220 216221 216222 |
** to iPos before returning.
*/
static void sqlite3Fts5PoslistSafeAppend(
Fts5Buffer *pBuf,
i64 *piPrev,
i64 iPos
){
| > | | | | | | | | > | 216281 216282 216283 216284 216285 216286 216287 216288 216289 216290 216291 216292 216293 216294 216295 216296 216297 216298 216299 216300 216301 216302 216303 216304 |
** to iPos before returning.
*/
static void sqlite3Fts5PoslistSafeAppend(
Fts5Buffer *pBuf,
i64 *piPrev,
i64 iPos
){
if( iPos>=*piPrev ){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
if( (iPos & colmask) != (*piPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
*piPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
*piPrev = iPos;
}
}
static int sqlite3Fts5PoslistWriterAppend(
Fts5Buffer *pBuf,
Fts5PoslistWriter *pWriter,
i64 iPos
){
|
| ︙ | ︙ | |||
224155 224156 224157 224158 224159 224160 224161 |
if( pColset->nCol==1 ){
pIter->base.pData = aCopy;
pIter->base.nData = p-aCopy;
return;
}
fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy);
}
| | | 224222 224223 224224 224225 224226 224227 224228 224229 224230 224231 224232 224233 224234 224235 224236 |
if( pColset->nCol==1 ){
pIter->base.pData = aCopy;
pIter->base.nData = p-aCopy;
return;
}
fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy);
}
if( p>=pEnd ){
pIter->base.pData = pIter->poslist.p;
pIter->base.nData = pIter->poslist.n;
return;
}
aCopy = p++;
iCurrent = *p++;
if( iCurrent & 0x80 ){
|
| ︙ | ︙ | |||
225951 225952 225953 225954 225955 225956 225957 |
static void fts5MergePrefixLists(
Fts5Index *p, /* FTS5 backend object */
Fts5Buffer *p1, /* First list to merge */
int nBuf, /* Number of buffers in array aBuf[] */
Fts5Buffer *aBuf /* Other lists to merge in */
){
#define fts5PrefixMergerNextPosition(p) \
| | | 226018 226019 226020 226021 226022 226023 226024 226025 226026 226027 226028 226029 226030 226031 226032 |
static void fts5MergePrefixLists(
Fts5Index *p, /* FTS5 backend object */
Fts5Buffer *p1, /* First list to merge */
int nBuf, /* Number of buffers in array aBuf[] */
Fts5Buffer *aBuf /* Other lists to merge in */
){
#define fts5PrefixMergerNextPosition(p) \
sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos)
#define FTS5_MERGE_NLIST 16
PrefixMerger aMerger[FTS5_MERGE_NLIST];
PrefixMerger *pHead = 0;
int i;
int nOut = 0;
Fts5Buffer out = {0, 0, 0};
Fts5Buffer tmp = {0, 0, 0};
|
| ︙ | ︙ | |||
230499 230500 230501 230502 230503 230504 230505 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 230566 230567 230568 230569 230570 230571 230572 230573 230574 230575 230576 230577 230578 230579 230580 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2021-06-14 20:41:20 e5a5acd6006133c5da4a7dd79726dbaa41c0d60ebeda890f848a6aafe5f9ef70", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | ︙ | |||
235425 235426 235427 235428 235429 235430 235431 | #endif return rc; } #endif /* SQLITE_CORE */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ | | | | 235492 235493 235494 235495 235496 235497 235498 235499 235500 235501 235502 235503 235504 235505 |
#endif
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
#if __LINE__!=235499
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID "2021-06-14 20:41:20 e5a5acd6006133c5da4a7dd79726dbaa41c0d60ebeda890f848a6aafe5f9alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/
|
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.36.0" #define SQLITE_VERSION_NUMBER 3036000 | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.36.0" #define SQLITE_VERSION_NUMBER 3036000 #define SQLITE_SOURCE_ID "2021-06-14 20:41:20 e5a5acd6006133c5da4a7dd79726dbaa41c0d60ebeda890f848a6aafe5f9ef70" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
/*
** An authorizer function for the SQL used to initialize the
** schema for the ticketing system. Only allow
**
** CREATE TABLE
** CREATE INDEX
** CREATE VIEW
**
** And for objects in "main" or "repository" whose names
** begin with "ticket" or "fx_". Also allow
**
** INSERT
** UPDATE
** DELETE
**
** But only for tables in "main" or "repository" whose names
** begin with "ticket", "sqlite_", or "fx_".
**
** Of particular importance for security is that this routine
** disallows data changes on the "config" table, as that could
** allow a malicious server to modify settings in such a way as
** to cause a remote code execution.
*/
static int ticket_schema_auth(
void *pNErr,
int eCode,
const char *z0,
const char *z1,
const char *z2,
const char *z3
){
switch( eCode ){
case SQLITE_CREATE_VIEW:
case SQLITE_CREATE_TABLE: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z0,"ticket",6)!=0
&& sqlite3_strnicmp(z0,"fx_",3)!=0
){
goto ticket_schema_error;
}
break;
}
case SQLITE_CREATE_INDEX: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z1,"ticket",6)!=0
| > > > > > > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
/*
** An authorizer function for the SQL used to initialize the
** schema for the ticketing system. Only allow
**
** CREATE TABLE
** CREATE INDEX
** CREATE VIEW
** DROP INDEX
** DROP VIEW
**
** And for objects in "main" or "repository" whose names
** begin with "ticket" or "fx_". Also allow
**
** INSERT
** UPDATE
** DELETE
**
** But only for tables in "main" or "repository" whose names
** begin with "ticket", "sqlite_", or "fx_".
**
** Of particular importance for security is that this routine
** disallows data changes on the "config" table, as that could
** allow a malicious server to modify settings in such a way as
** to cause a remote code execution.
**
** Use the "fossil test-db-prepare --auth-ticket SQL" command to perform
** manual testing of this authorizer.
*/
static int ticket_schema_auth(
void *pNErr,
int eCode,
const char *z0,
const char *z1,
const char *z2,
const char *z3
){
switch( eCode ){
case SQLITE_DROP_VIEW:
case SQLITE_CREATE_VIEW:
case SQLITE_CREATE_TABLE: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z0,"ticket",6)!=0
&& sqlite3_strnicmp(z0,"fx_",3)!=0
){
goto ticket_schema_error;
}
break;
}
case SQLITE_DROP_INDEX:
case SQLITE_CREATE_INDEX: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z1,"ticket",6)!=0
|
| ︙ | ︙ | |||
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
return SQLITE_OK;
ticket_schema_error:
if( pNErr ) *(int*)pNErr = 1;
return SQLITE_DENY;
}
/*
** Recreate the TICKET and TICKETCHNG tables.
*/
void ticket_create_table(int separateConnection){
char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
| > > > > > > > > > > > > > > | | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
return SQLITE_OK;
ticket_schema_error:
if( pNErr ) *(int*)pNErr = 1;
return SQLITE_DENY;
}
/*
** Activate the ticket schema authorizer. Must be followed by
** an eventual call to ticket_unrestrict_sql().
*/
void ticket_restrict_sql(int * pNErr){
db_set_authorizer(ticket_schema_auth,(void*)pNErr,"Ticket-Schema");
}
/*
** Deactivate the ticket schema authorizer.
*/
void ticket_unrestrict_sql(void){
db_clear_authorizer();
}
/*
** Recreate the TICKET and TICKETCHNG tables.
*/
void ticket_create_table(int separateConnection){
char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
ticket_restrict_sql(0);
if( separateConnection ){
if( db_transaction_nesting_depth() ) db_end_transaction(0);
db_init_database(g.zRepositoryName, zSql, 0);
}else{
db_multi_exec("%s", zSql/*safe-for-%s*/);
}
ticket_unrestrict_sql();
fossil_free(zSql);
}
/*
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
** available ticket artifacts.
*/
|
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 10 11 |
<title>Change Log</title>
<a name='v2_16'></a>
<h2>Changes for Version 2.16 (pending)</h2>
* The [/brlist|/brlist web page] allows the user to
select multiple branches to be displayed together in a single
timeline.
* The [./forum.wiki|Forum] provides a hyperlink on the author of each
post that goes to a timeline of recent posts by that same author.
* The [/help?cmd=merge|fossil merge] command now does a better job merging
branches where files have been renamed between the current branch and the
| > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<title>Change Log</title>
<a name='v2_16'></a>
<h2>Changes for Version 2.16 (pending)</h2>
* <b>Security:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate. <b>Upgrading to
the patch is recommended.</b>
* The [/brlist|/brlist web page] allows the user to
select multiple branches to be displayed together in a single
timeline.
* The [./forum.wiki|Forum] provides a hyperlink on the author of each
post that goes to a timeline of recent posts by that same author.
* The [/help?cmd=merge|fossil merge] command now does a better job merging
branches where files have been renamed between the current branch and the
|
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
list of the "[/help?cmd=all|fossil all ui]" command.
* Administrators can configure [./alerts|email alerts] to expire
a specific number of days (ex: 365) after the last user contact with
the Fossil server This can prevents alert emails being sent to
abandoned email accounts forever.
<a name='v2_15'></a>
| | > > > > | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
list of the "[/help?cmd=all|fossil all ui]" command.
* Administrators can configure [./alerts|email alerts] to expire
a specific number of days (ex: 365) after the last user contact with
the Fossil server This can prevents alert emails being sent to
abandoned email accounts forever.
<a name='v2_15'></a>
<h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)
and 2.15.2 on (2021-06-15)</h2>
* <b>Patch 2.15.2:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate. <b>Upgrading to
the patch is recommended.</b>
* <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
the patch is recommended.</b>
* The [./defcsp.md|default CSP] has been relaxed slightly to allow
images to be loaded from any URL. All other resources are still
locked down by default.
* The built-in skins all use the "[/help?cmd=mainmenu|mainmenu]"
setting to determine the content of the main menu.
The ability to edit the
"mainmenu" setting is added on the /Admin/Configuration page.
|
| ︙ | ︙ | |||
103 104 105 106 107 108 109 |
* Webpage that shows [/help?cmd=/whistory|history of a wiki page]
gained client-side UI to help with comparison between two arbitrary
versions of a wiki (by the means of anchoring a "baseline" version)
and the ability to squeeze several sequential edits made by the same
user into a single "recycled" row (the latest edit in that sequence).
<a name='v2_14'></a>
| | > > > > | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
* Webpage that shows [/help?cmd=/whistory|history of a wiki page]
gained client-side UI to help with comparison between two arbitrary
versions of a wiki (by the means of anchoring a "baseline" version)
and the ability to squeeze several sequential edits made by the same
user into a single "recycled" row (the latest edit in that sequence).
<a name='v2_14'></a>
<h2>Changes for Version 2.14 (2021-01-20) and Patch 2.14.1 on (2021-04-07)
and 2.14.2 on (2021-06-15)</h2>
* <b>Patch 2.14.2:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate. <b>Upgrading to
the patch is recommended.</b><
* <b>Patch 2.14.1:</b> Fix a data exfiltration bug in the server.
<b>Upgrading to the patch is recommended.</b>
* <b>Schema Update Notice #1:</b>
This release drops a trigger from the database schema (replacing
it with a TEMP trigger that is created as needed). This
change happens automatically the first time you
add content to a repository using Fossil 2.14 or later. No
action is needed on your part. However, if you upgrade to
version 2.14 and then later downgrade or otherwise use an earlier
|
| ︙ | ︙ |