Add the SQLITE_TESTCTRL_PRNG_SEED test control.
FossilOrigin-Name: 3ac5723164ae801e209ce525a5d94692767136f9d06be2a84883dcea677d02da
diff --git a/src/global.c b/src/global.c
index b512e6f..79b1d42 100644
--- a/src/global.c
+++ b/src/global.c
@@ -260,6 +260,7 @@
0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
+ 0, /* iPrngSeed */
};
/*
diff --git a/src/main.c b/src/main.c
index 6127006..81a76aa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3824,13 +3824,13 @@
break;
}
- /*
- ** Reset the PRNG back to its uninitialized state. The next call
- ** to sqlite3_randomness() will reseed the PRNG using a single call
- ** to the xRandomness method of the default VFS.
+ /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, unsigned int);
+ **
+ ** Use the integer value as the seed for SQLite's internal PRNG.
+ ** rather than the VFS xRandomness() function.
*/
- case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3_randomness(0,0);
+ case SQLITE_TESTCTRL_PRNG_SEED: {
+ sqlite3Config.iPrngSeed = va_arg(ap, unsigned int);
break;
}
diff --git a/src/os.c b/src/os.c
index 54b7fcf..0870102 100644
--- a/src/os.c
+++ b/src/os.c
@@ -258,7 +258,15 @@
}
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- return pVfs->xRandomness(pVfs, nByte, zBufOut);
+ if( sqlite3Config.iPrngSeed ){
+ memset(zBufOut, 0, nByte);
+ if( nByte>sizeof(unsigned) ) nByte = sizeof(unsigned int);
+ memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
+ return SQLITE_OK;
+ }else{
+ return pVfs->xRandomness(pVfs, nByte, zBufOut);
+ }
+
}
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
return pVfs->xSleep(pVfs, nMicro);
diff --git a/src/shell.c.in b/src/shell.c.in
index c5ca924..fa82cf2 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -9150,9 +9150,9 @@
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
#endif
{ "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
- { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" },
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
+ { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED" },
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" },
};
int testctrl = -1;
@@ -9227,6 +9227,7 @@
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
+ case SQLITE_TESTCTRL_PRNG_SEED:
if( nArg==3 ){
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 4dd14ac..5b3e5a1 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7335,7 +7335,7 @@
#define SQLITE_TESTCTRL_FIRST 5
#define SQLITE_TESTCTRL_PRNG_SAVE 5
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
-#define SQLITE_TESTCTRL_PRNG_RESET 7
+#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
#define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
@@ -7358,7 +7358,8 @@
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
-#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_PRNG_SEED 28
+#define SQLITE_TESTCTRL_LAST 28 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b41ba4e..166c465 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3464,6 +3464,7 @@
int bInternalFunctions; /* Internal SQL functions are visible */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
+ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
};
/*
diff --git a/src/test1.c b/src/test1.c
index 02a7aad..c582bb3 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -6373,7 +6373,28 @@
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
- sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
+ sqlite3_randomness(0,0);
+ return TCL_OK;
+}
+/*
+** tclcmd: prng_seed INT
+**
+** Establish TEXT as the seed for the PRNG
+*/
+static int SQLITE_TCLAPI prng_seed(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ unsigned int i;
+ if( objc!=2 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "PRNG-SEED-TEXT");
+ return TCL_ERROR;
+ }
+ if( Tcl_GetIntFromObj(objv[0],&i) ) return TCL_ERROR;
+ sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, (unsigned int)i);
+ sqlite3_randomness(0,0);
return TCL_OK;
}
@@ -7923,6 +7944,7 @@
{ "save_prng_state", save_prng_state, 0 },
{ "restore_prng_state", restore_prng_state, 0 },
{ "reset_prng_state", reset_prng_state, 0 },
+ { "prng_seed", prng_seed, 0 },
{ "database_never_corrupt", database_never_corrupt, 0},
{ "database_may_be_corrupt", database_may_be_corrupt, 0},
{ "optimization_control", optimization_control,0},