1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Factor out the logic that does quoting for the SQL quote() function, so that

it might be reused for other purposes.

FossilOrigin-Name: 8e98ba1eeb1a5a61b7cb2de337ef8bca3d07494266a50d62b9c6bc60ad0a955f
This commit is contained in:
drh
2021-12-10 21:01:24 +00:00
parent 27a9e1f615
commit ef95d5583b
5 changed files with 67 additions and 57 deletions

View File

@@ -1,5 +1,5 @@
C Rename\sthe\sinternal\sroutine\sconstructBloomFilter()\sto\nsqlite3ConstructBloomFilter().\sOSSFuzz\sis\sreporting\sa\scrash\swith\sa\sgarbled\nstack\sthat\swe\scannot\sreproduce.\sPerhaps\sthe\soriginal\s"constructBloomFilter()"\nname\sis\scolliding\swith\ssome\sinternal\sname\sused\sby\sOSSFuzz.\sWe'll\ssee\sif\sthis\nrename\sclears\sthe\sproblem. C Factor\sout\sthe\slogic\sthat\sdoes\squoting\sfor\sthe\sSQL\squote()\sfunction,\sso\sthat\nit\smight\sbe\sreused\sfor\sother\spurposes.
D 2021-12-10T17:36:16.695 D 2021-12-10T21:01:24.675
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -506,7 +506,7 @@ F src/delete.c 19814f621cde10b1771a0dea7fe25d3d7d39975b8d4be4888537d30860e7c08c
F src/expr.c 827179c78d2ca7cc318392811de8151c60eacf7ce804b13e61bb7ef38f954846 F src/expr.c 827179c78d2ca7cc318392811de8151c60eacf7ce804b13e61bb7ef38f954846
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 187b67af20c5795953a592832c5d985e4313fe503ebd8f95e3e9e9ad5a730bb5 F src/fkey.c 187b67af20c5795953a592832c5d985e4313fe503ebd8f95e3e9e9ad5a730bb5
F src/func.c 1cfb09d7ffca81238eccefdb0293e1f5b7cfebbd1816dfad5ec6024742a7496b F src/func.c 0f576a0c102485676266e63a796223e63c3cdb04baf3678ccc8bfeedba4a6fd4
F src/global.c 1f56aead86e8a18c4415638f5e6c4d0a0550427f4b3f5d065ba5164cc09c22e8 F src/global.c 1f56aead86e8a18c4415638f5e6c4d0a0550427f4b3f5d065ba5164cc09c22e8
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
@@ -547,7 +547,7 @@ F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
F src/pragma.c c536665ce8431c8b1efbf7e0a5c01852f49f7bf28f1954f8118b2d28e4a3797f F src/pragma.c c536665ce8431c8b1efbf7e0a5c01852f49f7bf28f1954f8118b2d28e4a3797f
F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad
F src/prepare.c 40961a1170a4c4151a90dae29dd00fc6c155f1af8246abeeeb8f0a10b3fb9719 F src/prepare.c 40961a1170a4c4151a90dae29dd00fc6c155f1af8246abeeeb8f0a10b3fb9719
F src/printf.c 5901672228f305f7d493cbc4e7d76a61a5caecdbc1cd06b1f9ec42ea4265cf8d F src/printf.c 9565aeb5af5376fd23c993b8da1ac37008fad65435a703316eef9f41229f702d
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c 4a1db4aadd802683db40ca2dbbb268187bd195f10cbdb7206dbd8ac988795571 F src/resolve.c 4a1db4aadd802683db40ca2dbbb268187bd195f10cbdb7206dbd8ac988795571
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
@@ -556,7 +556,7 @@ F src/shell.c.in 239bee1085d94964f02582b0714dc3fc85cfc16e27e95813e4dbc24bb215a7e
F src/sqlite.h.in 5999d6db0e65afbd686b76cddc385b310aa3815624edba43987913067f50e209 F src/sqlite.h.in 5999d6db0e65afbd686b76cddc385b310aa3815624edba43987913067f50e209
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839 F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839
F src/sqliteInt.h b4391c3c2ae0a8020ce0f543fc2b529f9bcdf72ab7ba3c31d170e3228169162f F src/sqliteInt.h e7dd69a85c53461c937d50c97f8efd9761b14f9bcfb63450809e85c100c08538
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -1934,7 +1934,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882 P 403e7312dd9a3fe493a21aceb82e387d6f152622d66c1b403c881597713e8cc3
R 2727e42f3726d0bce34928653c056def R 4fa3f8129d17f257f0557369c327b148
U drh U drh
Z 81c6addbec75f6f350e0d3032a7fdc73 Z 1eec60e7fbec94682a3271bf749ce5cf

View File

@@ -1 +1 @@
403e7312dd9a3fe493a21aceb82e387d6f152622d66c1b403c881597713e8cc3 8e98ba1eeb1a5a61b7cb2de337ef8bca3d07494266a50d62b9c6bc60ad0a955f

View File

@@ -1027,39 +1027,42 @@ static const char hexdigits[] = {
}; };
/* /*
** Implementation of the QUOTE() function. This function takes a single ** Append to pStr text that is the SQL literal representation of the
** argument. If the argument is numeric, the return value is the same as ** value contained in pValue.
** the argument. If the argument is NULL, the return value is the string
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/ */
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
assert( argc==1 ); /* As currently implemented, the string must be initially empty.
UNUSED_PARAMETER(argc); ** we might relax this requirement in the future, but that will
switch( sqlite3_value_type(argv[0]) ){ ** require enhancements to the implementation. */
assert( pStr!=0 && pStr->nChar==0 );
switch( sqlite3_value_type(pValue) ){
case SQLITE_FLOAT: { case SQLITE_FLOAT: {
double r1, r2; double r1, r2;
char zBuf[50]; const char *zVal;
r1 = sqlite3_value_double(argv[0]); r1 = sqlite3_value_double(pValue);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); sqlite3_str_appendf(pStr, "%!.15g", r1);
sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); zVal = sqlite3_str_value(pStr);
if( r1!=r2 ){ if( zVal ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8);
if( r1!=r2 ){
sqlite3_str_reset(pStr);
sqlite3_str_appendf(pStr, "%!.20e", r1);
}
} }
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
break; break;
} }
case SQLITE_INTEGER: { case SQLITE_INTEGER: {
sqlite3_result_value(context, argv[0]); sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue));
break; break;
} }
case SQLITE_BLOB: { case SQLITE_BLOB: {
char *zText = 0; char const *zBlob = sqlite3_value_blob(pValue);
char const *zBlob = sqlite3_value_blob(argv[0]); int nBlob = sqlite3_value_bytes(pValue);
int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */
assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4);
zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); if( pStr->accError==0 ){
if( zText ){ char *zText = pStr->zText;
int i; int i;
for(i=0; i<nBlob; i++){ for(i=0; i<nBlob; i++){
zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F]; zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
@@ -1069,42 +1072,47 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
zText[(nBlob*2)+3] = '\0'; zText[(nBlob*2)+3] = '\0';
zText[0] = 'X'; zText[0] = 'X';
zText[1] = '\''; zText[1] = '\'';
sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); pStr->nChar = nBlob*2 + 3;
sqlite3_free(zText);
} }
break; break;
} }
case SQLITE_TEXT: { case SQLITE_TEXT: {
int i,j; const unsigned char *zArg = sqlite3_value_text(pValue);
u64 n; sqlite3_str_appendf(pStr, "%Q", zArg);
const unsigned char *zArg = sqlite3_value_text(argv[0]);
char *z;
if( zArg==0 ) return;
for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
z = contextMalloc(context, ((i64)i)+((i64)n)+3);
if( z ){
z[0] = '\'';
for(i=0, j=1; zArg[i]; i++){
z[j++] = zArg[i];
if( zArg[i]=='\'' ){
z[j++] = '\'';
}
}
z[j++] = '\'';
z[j] = 0;
sqlite3_result_text(context, z, j, sqlite3_free);
}
break; break;
} }
default: { default: {
assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); assert( sqlite3_value_type(pValue)==SQLITE_NULL );
sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); sqlite3_str_append(pStr, "NULL", 4);
break; break;
} }
} }
} }
/*
** Implementation of the QUOTE() function.
**
** The quote(X) function returns the text of an SQL literal which is the
** value of its argument suitable for inclusion into an SQL statement.
** Strings are surrounded by single-quotes with escapes on interior quotes
** as needed. BLOBs are encoded as hexadecimal literals. Strings with
** embedded NUL characters cannot be represented as string literals in SQL
** and hence the returned string literal is truncated prior to the first NUL.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3_str str;
sqlite3 *db = sqlite3_context_db_handle(context);
assert( argc==1 );
UNUSED_PARAMETER(argc);
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3QuoteValue(&str,argv[0]);
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
SQLITE_DYNAMIC);
if( str.accError==SQLITE_NOMEM ){
sqlite3_result_error_nomem(context);
}
}
/* /*
** The unicode() function. Return the integer unicode code-point value ** The unicode() function. Return the integer unicode code-point value
** for the first character of the input string. ** for the first character of the input string.

View File

@@ -916,7 +916,7 @@ void sqlite3_str_vappendf(
** Return the number of bytes of text that StrAccum is able to accept ** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero. ** after the attempted enlargement. The value returned might be zero.
*/ */
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew; char *zNew;
assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){ if( p->accError ){

View File

@@ -4684,6 +4684,7 @@ Select *sqlite3SelectDup(sqlite3*,const Select*,int);
FuncDef *sqlite3FunctionSearch(int,const char*); FuncDef *sqlite3FunctionSearch(int,const char*);
void sqlite3InsertBuiltinFuncs(FuncDef*,int); void sqlite3InsertBuiltinFuncs(FuncDef*,int);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
void sqlite3QuoteValue(StrAccum*,sqlite3_value*);
void sqlite3RegisterBuiltinFunctions(void); void sqlite3RegisterBuiltinFunctions(void);
void sqlite3RegisterDateTimeFunctions(void); void sqlite3RegisterDateTimeFunctions(void);
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
@@ -4970,6 +4971,7 @@ int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *); int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
int sqlite3StrAccumEnlarge(StrAccum*, int);
char *sqlite3StrAccumFinish(StrAccum*); char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumSetError(StrAccum*, u8); void sqlite3StrAccumSetError(StrAccum*, u8);
void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);