aboutsummaryrefslogtreecommitdiff
path: root/ext/misc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/misc')
-rw-r--r--ext/misc/fileio.c2
-rw-r--r--ext/misc/vtablog.c55
-rw-r--r--ext/misc/zipfile.c22
-rw-r--r--ext/misc/zorder.c60
4 files changed, 119 insertions, 20 deletions
diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c
index 01d9c220f..22d61df61 100644
--- a/ext/misc/fileio.c
+++ b/ext/misc/fileio.c
@@ -899,9 +899,9 @@ static int fsdirFilter(
){
const char *zDir = 0;
fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ int i;
(void)idxStr;
fsdirResetCursor(pCur);
- int i;
if( idxNum==0 ){
fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c
index e8f084e1b..44acc32e6 100644
--- a/ext/misc/vtablog.c
+++ b/ext/misc/vtablog.c
@@ -14,6 +14,13 @@
** on stdout when its key interfaces are called. This is intended for
** interactive analysis and debugging of virtual table interfaces.
**
+** To build this extension as a separately loaded shared library or
+** DLL, use compiler command-lines similar to the following:
+**
+** (linux) gcc -fPIC -shared vtablog.c -o vtablog.so
+** (mac) clang -fPIC -dynamiclib vtablog.c -o vtablog.dylib
+** (windows) cl vtablog.c -link -dll -out:vtablog.dll
+**
** Usage example:
**
** .load ./vtablog
@@ -436,6 +443,39 @@ static int vtablogFilter(
}
/*
+** Return an sqlite3_index_info operator name in static space.
+** The name is possibly overwritten on subsequent calls.
+*/
+static char *vtablogOpName(unsigned char op){
+ static char zUnknown[30];
+ char *zOut;
+ switch( op ){
+ case SQLITE_INDEX_CONSTRAINT_EQ: zOut = "EQ"; break;
+ case SQLITE_INDEX_CONSTRAINT_GT: zOut = "GT"; break;
+ case SQLITE_INDEX_CONSTRAINT_LE: zOut = "LE"; break;
+ case SQLITE_INDEX_CONSTRAINT_LT: zOut = "LT"; break;
+ case SQLITE_INDEX_CONSTRAINT_GE: zOut = "GE"; break;
+ case SQLITE_INDEX_CONSTRAINT_MATCH: zOut = "MATCH"; break;
+ case SQLITE_INDEX_CONSTRAINT_LIKE: zOut = "LIKE"; break;
+ case SQLITE_INDEX_CONSTRAINT_GLOB: zOut = "GLOB"; break;
+ case SQLITE_INDEX_CONSTRAINT_REGEXP: zOut = "REGEXP"; break;
+ case SQLITE_INDEX_CONSTRAINT_NE: zOut = "NE"; break;
+ case SQLITE_INDEX_CONSTRAINT_ISNOT: zOut = "ISNOT"; break;
+ case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: zOut = "ISNOTNULL"; break;
+ case SQLITE_INDEX_CONSTRAINT_ISNULL: zOut = "ISNULL"; break;
+ case SQLITE_INDEX_CONSTRAINT_IS: zOut = "IS"; break;
+ case SQLITE_INDEX_CONSTRAINT_LIMIT: zOut = "LIMIT"; break;
+ case SQLITE_INDEX_CONSTRAINT_OFFSET: zOut = "OFFSET"; break;
+ case SQLITE_INDEX_CONSTRAINT_FUNCTION: zOut = "FUNCTION"; break;
+ default:
+ sqlite3_snprintf(sizeof(zUnknown),zUnknown,"%d",op);
+ zOut = zUnknown;
+ break;
+ }
+ return zOut;
+}
+
+/*
** SQLite will invoke this method one or more times while planning a query
** that uses the vtablog virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
@@ -451,14 +491,23 @@ static int vtablogBestIndex(
printf(" colUsed: 0x%016llx\n", p->colUsed);
printf(" nConstraint: %d\n", p->nConstraint);
for(i=0; i<p->nConstraint; i++){
+ sqlite3_value *pVal = 0;
+ int rc = sqlite3_vtab_rhs_value(p, i, &pVal);
printf(
- " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n",
+ " constraint[%d]: col=%d termid=%d op=%s usabled=%d coll=%s rhs=",
i,
p->aConstraint[i].iColumn,
p->aConstraint[i].iTermOffset,
- p->aConstraint[i].op,
+ vtablogOpName(p->aConstraint[i].op),
p->aConstraint[i].usable,
- sqlite3_vtab_collation(p,i));
+ sqlite3_vtab_collation(p,i)
+ );
+ if( rc==SQLITE_OK ){
+ vtablogQuote(pVal);
+ printf("\n");
+ }else{
+ printf("N/A\n");
+ }
}
printf(" nOrderBy: %d\n", p->nOrderBy);
for(i=0; i<p->nOrderBy; i++){
diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c
index 2377457df..9e78e7230 100644
--- a/ext/misc/zipfile.c
+++ b/ext/misc/zipfile.c
@@ -116,6 +116,7 @@ static const char ZIPFILE_SCHEMA[] =
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
#define ZIPFILE_BUFFER_SIZE (64*1024)
+#define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */
/*
@@ -672,6 +673,7 @@ static int zipfileReadLFH(
pLFH->szUncompressed = zipfileRead32(aRead);
pLFH->nFile = zipfileRead16(aRead);
pLFH->nExtra = zipfileRead16(aRead);
+ if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR;
}
return rc;
}
@@ -885,8 +887,12 @@ static int zipfileGetEntry(
pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
pNew->iDataOff += lfh.nFile + lfh.nExtra;
if( aBlob && pNew->cds.szCompressed ){
- pNew->aData = &pNew->aExtra[nExtra];
- memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
+ if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){
+ rc = SQLITE_CORRUPT;
+ }else{
+ pNew->aData = &pNew->aExtra[nExtra];
+ memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
+ }
}
}else{
*pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
@@ -1673,6 +1679,11 @@ static int zipfileUpdate(
zPath = (const char*)sqlite3_value_text(apVal[2]);
if( zPath==0 ) zPath = "";
nPath = (int)strlen(zPath);
+ if( nPath>ZIPFILE_MX_NAME ){
+ zipfileTableErr(pTab, "filename too long; max: %d bytes",
+ ZIPFILE_MX_NAME);
+ rc = SQLITE_CONSTRAINT;
+ }
mTime = zipfileGetTime(apVal[4]);
}
@@ -2034,6 +2045,13 @@ static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
rc = SQLITE_ERROR;
goto zipfile_step_out;
}
+ if( nName>ZIPFILE_MX_NAME ){
+ zErr = sqlite3_mprintf(
+ "filename argument to zipfile() too big; max: %d bytes",
+ ZIPFILE_MX_NAME);
+ rc = SQLITE_ERROR;
+ goto zipfile_step_out;
+ }
/* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
** deflate compression) or NULL (choose automatically). */
diff --git a/ext/misc/zorder.c b/ext/misc/zorder.c
index c385d3c3c..c4c5fcdc7 100644
--- a/ext/misc/zorder.c
+++ b/ext/misc/zorder.c
@@ -16,6 +16,17 @@
**
** unzorder(Z,N,I) Extract the I-th dimension from N-dimensional
** Morton code Z.
+**
+** Compiling:
+**
+** (linux) gcc -fPIC -shared zorder.c -o zorder.so
+** (mac) clang -fPIC -dynamiclib zorder.c -o zorder.dylib
+** (windows) cl zorder.c -link -dll -out:zorder.dll
+**
+** Usage example:
+**
+** .load ./zorder
+** SELECT zorder(1,2,3,4);
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
@@ -25,43 +36,53 @@ SQLITE_EXTENSION_INIT1
/*
** Functions: zorder(X0,X1,....)
**
-** Convert integers X0, X1, ... into morton code.
+** Convert integers X0, X1, ... into morton code. There must be at least
+** two arguments. There may be no more than 24 arguments.
**
-** The output is a signed 64-bit integer. If any argument is too large,
-** an error is thrown.
+** The output is a signed 64-bit integer. If any argument is too large
+** to be successfully encoded into a morton code, an error is raised.
*/
static void zorderFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- sqlite3_int64 z, x[63];
+ sqlite3_int64 z, x[24];
int i, j;
z = 0;
+ if( argc<2 || argc>24 ){
+ sqlite3_result_error(context,
+ "zorder() needs between 2 and 24 arguments4", -1);
+ return;
+ }
for(i=0; i<argc; i++){
x[i] = sqlite3_value_int64(argv[i]);
}
- if( argc>0 ){
- for(i=0; i<63; i++){
- j = i%argc;
- z |= (x[j]&1)<<i;
- x[j] >>= 1;
- }
+ for(i=0; i<63; i++){
+ j = i%argc;
+ z |= (x[j]&1)<<i;
+ x[j] >>= 1;
}
sqlite3_result_int64(context, z);
for(i=0; i<argc; i++){
if( x[i] ){
- sqlite3_result_error(context, "parameter too large", -1);
+ char *z = sqlite3_mprintf(
+ "the %r argument to zorder() (%lld) is too large "
+ "for a 64-bit %d-dimensional Morton code",
+ i+1, sqlite3_value_int64(argv[i]), argc);
+ sqlite3_result_error(context, z, -1);
+ sqlite3_free(z);
+ break;
}
}
}
/*
-** Functions: unzorder(Z,N,I)
+** Function: unzorder(Z,N,K)
**
-** Assuming that Z is an N-dimensional Morton code, extract the I-th
-** dimension.
+** Assuming that Z is an N-dimensional Morton code, extract the K-th
+** dimension. K is between 0 and N-1. N must be between 2 and 24.
*/
static void unzorderFunc(
sqlite3_context *context,
@@ -72,7 +93,18 @@ static void unzorderFunc(
int j, k;
z = sqlite3_value_int64(argv[0]);
n = sqlite3_value_int64(argv[1]);
+ if( n<2 || n>24 ){
+ sqlite3_result_error(context,
+ "N argument to unzorder(Z,N,K) should be between 2 and 24",
+ -1);
+ return;
+ }
i = sqlite3_value_int64(argv[2]);
+ if( i<0 || i>=n ){
+ sqlite3_result_error(context,
+ "K argument to unzorder(Z,N,K) should be between 0 and N-1", -1);
+ return;
+ }
x = 0;
for(k=0, j=i; j<63; j+=n, k++){
x |= ((z>>j)&1)<<k;