From: drh <> Date: Fri, 28 Apr 2023 17:38:35 +0000 (+0000) Subject: Improvements to the accuracy of json_error(). Add the extension SQL X-Git-Tag: version-3.42.0~73^2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e7efe37645453fac5ca98f8a9837f34d14f75b6;p=thirdparty%2Fsqlite.git Improvements to the accuracy of json_error(). Add the extension SQL functions random_json(SEED) and random_json5(SEED). FossilOrigin-Name: 8d09dc1c45a8026b94f70273d064e47939f30cadedc17548b5a26ba054a8d3a7 --- diff --git a/ext/misc/randomjson.c b/ext/misc/randomjson.c new file mode 100644 index 0000000000..3a6f545fe6 --- /dev/null +++ b/ext/misc/randomjson.c @@ -0,0 +1,202 @@ +/* +** 2023-04-28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements a the random_json(SEED) and +** random_json5(SEED) functions. Given a numeric SEED value, these +** routines generate pseudo-random JSON or JSON5, respectively. The +** same value is always generated for the same seed. +** +** These SQL functions are intended for testing. They do not have any +** practical real-world use, that we know of. +** +** COMPILE: +** +** gcc --shared -fPIC -o randomjson.so -I. ext/misc/randomjson.c +** +** USING FROM THE CLI: +** +** .load ./randomjson +** SELECT random_json(1); +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +/* Pseudo-random number generator */ +typedef struct Prng { + unsigned int x, y; +} Prng; + +/* Reseed the PRNG */ +static void prngSeed(Prng *p, unsigned int iSeed){ + p->x = iSeed | 1; + p->y = iSeed; +} + +/* Extract a random number */ +static unsigned int prngInt(Prng *p){ + p->x = (p->x>>1) ^ ((1+~(p->x&1)) & 0xd0000001); + p->y = p->y*1103515245 + 12345; + return p->x ^ p->y; +} + +static const char *azJsonAtoms[] = { + /* JSON /* JSON-5 */ + "0", "0", + "1", "1", + "-1", "-1", + "2", "+2", + "3", "3", + "2.5", "2.5", + "0.75", ".75", + "-4.0e2", "-4.e2", + "5.0e-3", "+5e-3", + "0", "0x0", + "512", "0x200", + "256", "+0x100", + "-2748", "-0xabc", + "true", "true", + "false", "false", + "null", "null", + "9.0e999", "Infinity", + "-9.0e999", "-Infinity", + "9.0e999", "+Infinity", + "null", "NaN", + "-0.0005123", "-0.0005123", + "4.35e-3", "+4.35e-3", + "\"gem\\\"hay\"", "\"gem\\\"hay\"", + "\"icy'joy\"", "'icy\\'joy\'", + "\"keylog\"", "\"key\\\nlog\"", + "\"mix\\\\\\tnet\"", "\"mix\\\\\\tnet\"", + "{}", "{}", + "[]", "[]", + "[]", "[/*empty*/]", + "{}", "{//empty\n}", + "\"ask\"", "\"ask\"", + "\"bag\"", "\"bag\"", + "\"can\"", "\"can\"", + "\"day\"", "\"day\"", + "\"end\"", "'end'", + "\"fly\"", "\"fly\"", + "\"\"", "\"\"", +}; +static const char *azJsonTemplate[] = { + /* JSON JSON-5 */ + "{\"a\":%,\"b\":%,\"c\":%}", "{a:%,b:%,c:%}", + "{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"e\":%}", "{a:%,b:%,c:%,d:%,e:%}", + "{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"\":%}", "{a:%,b:%,c:%,d:%,\"\":%}", + "{\"d\":%}", "{d:%}", + "{\"eeee\":%, \"ffff\":%}", "{eeee:% /*and*/, ffff:%}", + "{\"$g\":%,\"_h_\":%}", "{$g:%,_h_:%,}", + "{\"x\":%,\n \"y\":%}", "{\"x\":%,\n \"y\":%}", + "{\"a b c d\":%,\"e\":%,\"f\":%,\"x\":%,\"y\":%}", + "{\"a b c d\":%,e:%,f:%,x:%,y:%}", + "{\"Z\":%}", "{Z:%,}", + "[%]", "[%,]", + "[%,%]", "[%,%]", + "[%,%,%]", "[%,%,%,]", + "[%,%,%,%]", "[%,%,%,%]", + "[%,%,%,%,%]", "[%,%,%,%,%]", +}; + +#define count(X) (sizeof(X)/sizeof(X[0])) + +#define STRSZ 10000 + +static void jsonExpand( + const char *zSrc, + char *zDest, + Prng *p, + int eType, /* 0 for JSON, 1 for JSON5 */ + unsigned int r /* Growth probability 0..1000. 0 means no growth */ +){ + unsigned int i, j, k; + const char *z; + size_t n; + + j = 0; + if( zSrc==0 ){ + k = prngInt(p)%(count(azJsonTemplate)/2); + k = k*2 + eType; + zSrc = azJsonTemplate[k]; + } + if( strlen(zSrc)>=STRSZ/10 ) r = 0; + for(i=0; zSrc[i]; i++){ + if( zSrc[i]!='%' ){ + if( jhas5 = 1; x = k; }else{ - pParse->iErr = j; + if( x!=-1 ) pParse->iErr = j; return -1; } } @@ -1114,7 +1114,7 @@ json_parse_restart: } x = jsonParseValue(pParse, j); if( x!=(-5) ){ - pParse->iErr = j; + if( x!=(-1) ) pParse->iErr = j; return -1; } j = pParse->iErr+1; @@ -1123,7 +1123,7 @@ json_parse_restart: x = jsonParseValue(pParse, j); pParse->iDepth--; if( x<=0 ){ - pParse->iErr = j; + if( x!=(-1) ) pParse->iErr = j; return -1; } j = x; @@ -1174,7 +1174,7 @@ json_parse_restart: if( pParse->nNode!=(u32)iThis+1 ) pParse->has5 = 1; break; } - pParse->iErr = j; + if( x!=(-1) ) pParse->iErr = j; return -1; } j = x;