/* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ static const unsigned char zSrc[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" ".-!,:*^+=_|?/<> "; int iMin, iMax, n, r, i; unsigned char zBuf[1000]; /* It used to be possible to call randstr() with any number of arguments, ** but now it is registered with SQLite as requiring exactly 2. */ assert(argc==2); iMin = sqlite3_value_int(argv[0]); if( iMin<0 ) iMin = 0; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; iMax = sqlite3_value_int(argv[1]); if( iMax<iMin ) iMax = iMin; if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; n = iMin; if( iMax>iMin ){ sqlite3_randomness(sizeof(r), &r); r &= 0x7fffffff; n += r%(iMax + 1 - iMin); } assert( n<sizeof(zBuf) ); sqlite3_randomness(n, zBuf); for(i=0; i<n; i++){ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)]; } zBuf[n] = 0; sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT); }
static int sqlcipher_ltc_activate(void *ctx) { unsigned char random_buffer[FORTUNA_MAX_SZ]; #ifndef SQLCIPHER_LTC_NO_MUTEX_RAND if(ltc_rand_mutex == NULL){ ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); } sqlite3_mutex_enter(ltc_rand_mutex); #endif sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); if(ltc_init == 0) { if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR; if(register_cipher(&rijndael_desc) < 0) return SQLITE_ERROR; if(register_hash(&sha512_desc) < 0) return SQLITE_ERROR; if(register_hash(&sha256_desc) < 0) return SQLITE_ERROR; if(register_hash(&sha1_desc) < 0) return SQLITE_ERROR; if(fortuna_start(&prng) != CRYPT_OK) { return SQLITE_ERROR; } ltc_init = 1; } ltc_ref_count++; #ifndef SQLCIPHER_TEST sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer); #endif #ifndef SQLCIPHER_LTC_NO_MUTEX_RAND sqlite3_mutex_leave(ltc_rand_mutex); #endif if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) { return SQLITE_ERROR; } sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); return SQLITE_OK; }
/* ** Open a connection to the server. The server is defined by the following ** variables: ** ** pUrlData->name Name of the server. Ex: www.fossil-scm.org ** pUrlData->port TCP/IP port. Ex: 80 ** pUrlData->isHttps Use TLS for the connection ** ** Return the number of errors. */ int transport_open(UrlData *pUrlData){ int rc = 0; if( transport.isOpen==0 ){ if( pUrlData->isSsh ){ rc = transport_ssh_open(pUrlData); if( rc==0 ) transport.isOpen = 1; }else if( pUrlData->isHttps ){ #ifdef FOSSIL_ENABLE_SSL rc = ssl_open(pUrlData); if( rc==0 ) transport.isOpen = 1; #else socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support"); rc = 1; #endif }else if( pUrlData->isFile ){ sqlite3_uint64 iRandId; sqlite3_randomness(sizeof(iRandId), &iRandId); transport.zOutFile = mprintf("%s-%llu-out.http", g.zRepositoryName, iRandId); transport.zInFile = mprintf("%s-%llu-in.http", g.zRepositoryName, iRandId); transport.pFile = fossil_fopen(transport.zOutFile, "wb"); if( transport.pFile==0 ){ fossil_fatal("cannot output temporary file: %s", transport.zOutFile); } transport.isOpen = 1; }else{ rc = socket_open(pUrlData); if( rc==0 ) transport.isOpen = 1; } } return rc; }
static int sqlcipher_ltc_activate(void *ctx) { ltc_ctx *ltc = (ltc_ctx*)ctx; int random_buffer_sz = 32; unsigned char random_buffer[random_buffer_sz]; if(ltc_init == 0) { if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR; if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR; if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR; ltc_init = 1; } if(fortuna_start(&(ltc->prng)) != CRYPT_OK) { return SQLITE_ERROR; } sqlite3_randomness(random_buffer_sz, &random_buffer); if(sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz) != SQLITE_OK) { return SQLITE_ERROR; } if(sqlcipher_ltc_add_random(ctx, <c, sizeof(ltc_ctx*)) != SQLITE_OK) { return SQLITE_ERROR; } if(fortuna_ready(&(ltc->prng)) != CRYPT_OK) { return SQLITE_ERROR; } return SQLITE_OK; }
/* ** Create a temporary file name in zBuf. zBuf must be allocated ** by the calling process and must be big enough to hold at least ** pVfs->mxPathname bytes. */ static int getTempname(int nBuf, char *zBuf){ static const char *azDirs[] = { 0, #ifdef __SYMBIAN32__ "c:\\system\\temp\\sqlite3", "c:\\temp", "c:", #else "/var/tmp", "/usr/tmp", "/tmp", #endif ".", }; static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; struct stat buf; const char *zDir = "."; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ SimulateIOError( return SQLITE_IOERR ); azDirs[0] = sqlite3_temp_directory; for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ if( azDirs[i]==0 ) continue; if( stat(azDirs[i], &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; if( access(azDirs[i], 07) ) continue; zDir = azDirs[i]; break; } /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){ return SQLITE_ERROR; } do{ sqlite3_snprintf(nBuf-17, zBuf, "%s" SEP_STR SQLITE_TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; }while( access(zBuf,0)==0 ); return SQLITE_OK; }
/* ** Write a BLOB into a random filename. Return the name of the file. */ char *write_blob_to_temp_file(Blob *pBlob){ sqlite3_uint64 r; char *zOut = 0; do{ sqlite3_free(zOut); sqlite3_randomness(8, &r); zOut = sqlite3_mprintf("file-%08llx", r); }while( file_size(zOut)>=0 ); blob_write_to_file(pBlob, zOut); return zOut; }
ikptr ik_sqlite3_randomness (ikptr s_bytevector, ikpcb * pcb) { #ifdef HAVE_SQLITE3_RANDOMNESS int len = IK_BYTEVECTOR_LENGTH(s_bytevector); uint8_t * ptr = IK_BYTEVECTOR_DATA_VOIDP(s_bytevector); sqlite3_randomness(len, ptr); return s_bytevector; #else feature_failure(__func__); #endif }
/* ** Implementation of random(). Return a random integer. */ static void randomFunc( sqlite3_context *context, int NotUsed, sqlite3_value **NotUsed2 ){ sqlite_int64 r; UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_randomness(sizeof(r), &r); if( (r<<1)==0 ) r = 0; /* Prevent 0x8000.... as the result so that we */ /* can always do abs() of the result */ sqlite3_result_int64(context, r); }
/** @SYMTestCaseID PDS-SQLITE3-UT-4038 @SYMTestCaseDesc Database handle SQLITE3 tests. List of called SQLITE3 functions: - sqlite3_db_status; - sqlite3_file_control; - sqlite3_limit; - sqlite3_next_stmt; - sqlite3_randomness; @SYMTestPriority High @SYMTestActions Database handle SQLITE3 tests. @SYMTestExpectedResults Test must not fail @SYMREQ REQ10424 */ static void TestSqliteApi2() { int used = 0; int high = 0; int lock = -1; int limit = 0; sqlite3_stmt* next = 0; int err; unsigned char buf[10]; TEST(TheDb != 0); err = sqlite3_db_status(TheDb, SQLITE_DBSTATUS_LOOKASIDE_USED, &used, &high, 0); TEST2(err, SQLITE_OK); PrintI("Lookaside slots: %d\r\n", used); PrintI("Max used lookaside slots: %d\r\n", high); err = sqlite3_file_control(TheDb, "main", SQLITE_FCNTL_LOCKSTATE, &lock); TEST2(err, SQLITE_OK); TEST2(lock, SQLITE_LOCK_NONE); limit = sqlite3_limit(TheDb, SQLITE_LIMIT_LENGTH, -1); TEST(limit > 0); next = sqlite3_next_stmt(TheDb, 0); TEST(!next); memset(buf, 0, sizeof(buf)); sqlite3_randomness(8, buf); memset(buf, 0, sizeof(buf)); sqlite3_randomness(7, buf); memset(buf, 0, sizeof(buf)); sqlite3_randomness(3, buf); }
/* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at pVfs->mxPathname characters. */ static int getTempname(int nBuf, char *zBuf ){ static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; char zTempPathBuf[3]; PSZ zTempPath = (PSZ)&zTempPathBuf; if( sqlite3_temp_directory ){ zTempPath = sqlite3_temp_directory; }else{ if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ ULONG ulDriveNum = 0, ulDriveMap = 0; DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) ); } } } } /* Strip off a trailing slashes or backslashes, otherwise we would get * * multiple (back)slashes which causes DosOpen() to fail. * * Trailing spaces are not allowed, either. */ j = sqlite3Strlen30(zTempPath); while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || zTempPath[j-1] == ' ' ) ){ j--; } zTempPath[j] = '\0'; if( !sqlite3_temp_directory ){ char *zTempPathUTF = convertCpPathToUtf8( zTempPath ); sqlite3_snprintf( nBuf-30, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF ); free( zTempPathUTF ); }else{ sqlite3_snprintf( nBuf-30, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); } j = sqlite3Strlen30( zBuf ); sqlite3_randomness( 20, &zBuf[j] ); for( i = 0; i < 20; i++, j++ ){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; OSTRACE2( "TEMP FILENAME: %s\n", zBuf ); return SQLITE_OK; }
/* ** Implementation of randomblob(N). Return a random blob ** that is N bytes long. */ static void randomBlob( sqlite3_context *context, int argc, sqlite3_value **argv ){ int n; unsigned char *p; assert( argc==1 ); UNUSED_PARAMETER(argc); n = sqlite3_value_int(argv[0]); if( n<1 ){ n = 1; } p = contextMalloc(context, n); if( p ){ sqlite3_randomness(n, p); sqlite3_result_blob(context, (char*)p, n, sqlite3_free); } }
/* ** Implementation of random(). Return a random integer. */ static void randomFunc( sqlite3_context *context, int NotUsed, sqlite3_value **NotUsed2 ){ sqlite_int64 r; UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_randomness(sizeof(r), &r); if( r<0 ){ /* We need to prevent a random number of 0x8000000000000000 ** (or -9223372036854775808) since when you do abs() of that ** number of you get the same value back again. To do this ** in a way that is testable, mask the sign bit off of negative ** values, resulting in a positive value. Then take the ** 2s complement of that positive value. The end result can ** therefore be no less than -9223372036854775807. */ r = -(r ^ (((sqlite3_int64)1)<<63)); } sqlite3_result_int64(context, r); }
/* ** Open a connection to the server. The server is defined by the following ** global variables: ** ** g.urlName Name of the server. Ex: www.fossil-scm.org ** g.urlPort TCP/IP port. Ex: 80 ** g.urlIsHttps Use TLS for the connection ** ** Return the number of errors. */ int transport_open(void){ int rc = 0; if( transport.isOpen==0 ){ if( g.urlIsSsh ){ Blob cmd; blob_zero(&cmd); shell_escape(&cmd, g.urlFossil); blob_append(&cmd, " test-http ", -1); shell_escape(&cmd, g.urlPath); /* fprintf(stdout, "%s\n", blob_str(&cmd)); */ fprintf(sshOut, "%s\n", blob_str(&cmd)); fflush(sshOut); blob_reset(&cmd); }else if( g.urlIsHttps ){ #ifdef FOSSIL_ENABLE_SSL rc = ssl_open(); if( rc==0 ) transport.isOpen = 1; #else socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support"); rc = 1; #endif }else if( g.urlIsFile ){ sqlite3_uint64 iRandId; sqlite3_randomness(sizeof(iRandId), &iRandId); transport.zOutFile = mprintf("%s-%llu-out.http", g.zRepositoryName, iRandId); transport.zInFile = mprintf("%s-%llu-in.http", g.zRepositoryName, iRandId); transport.pFile = fopen(transport.zOutFile, "wb"); if( transport.pFile==0 ){ fossil_fatal("cannot output temporary file: %s", transport.zOutFile); } transport.isOpen = 1; }else{ rc = socket_open(); if( rc==0 ) transport.isOpen = 1; } } return rc; }
/* ** This is the callback from a quota-over-limit. */ static void tclQuotaCallback( const char *zFilename, /* Name of file whose size increases */ sqlite3_int64 *piLimit, /* IN/OUT: The current limit */ sqlite3_int64 iSize, /* Total size of all files in the group */ void *pArg /* Client data */ ){ TclQuotaCallback *p; /* Callback script object */ Tcl_Obj *pEval; /* Script to evaluate */ Tcl_Obj *pVarname; /* Name of variable to pass as 2nd arg */ unsigned int rnd; /* Random part of pVarname */ int rc; /* Tcl error code */ p = (TclQuotaCallback *)pArg; if( p==0 ) return; pVarname = Tcl_NewStringObj("::piLimit_", -1); Tcl_IncrRefCount(pVarname); sqlite3_randomness(sizeof(rnd), (void *)&rnd); Tcl_AppendObjToObj(pVarname, Tcl_NewIntObj((int)(rnd&0x7FFFFFFF))); Tcl_ObjSetVar2(p->interp, pVarname, 0, Tcl_NewWideIntObj(*piLimit), 0); pEval = Tcl_DuplicateObj(p->pScript); Tcl_IncrRefCount(pEval); Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj(zFilename, -1)); Tcl_ListObjAppendElement(0, pEval, pVarname); Tcl_ListObjAppendElement(0, pEval, Tcl_NewWideIntObj(iSize)); rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL); if( rc==TCL_OK ){ Tcl_Obj *pLimit = Tcl_ObjGetVar2(p->interp, pVarname, 0, 0); rc = Tcl_GetWideIntFromObj(p->interp, pLimit, piLimit); Tcl_UnsetVar(p->interp, Tcl_GetString(pVarname), 0); } Tcl_DecrRefCount(pEval); Tcl_DecrRefCount(pVarname); if( rc!=TCL_OK ) Tcl_BackgroundError(p->interp); }
/* ** Flush the write-list as if xSync() had been called on file handle ** pFile. If isCrash is true, simulate a crash. */ static int writeListSync(CrashFile *pFile, int isCrash){ int rc = SQLITE_OK; int iDc = g.iDeviceCharacteristics; WriteBuffer *pWrite; WriteBuffer **ppPtr; /* If this is not a crash simulation, set pFinal to point to the ** last element of the write-list that is associated with file handle ** pFile. ** ** If this is a crash simulation, set pFinal to an arbitrarily selected ** element of the write-list. */ WriteBuffer *pFinal = 0; if( !isCrash ){ for(pWrite=g.pWriteList; pWrite; pWrite=pWrite->pNext){ if( pWrite->pFile==pFile ){ pFinal = pWrite; } } }else if( iDc&(SQLITE_IOCAP_SEQUENTIAL|SQLITE_IOCAP_SAFE_APPEND) ){ int nWrite = 0; int iFinal; for(pWrite=g.pWriteList; pWrite; pWrite=pWrite->pNext) nWrite++; sqlite3_randomness(sizeof(int), &iFinal); iFinal = ((iFinal<0)?-1*iFinal:iFinal)%nWrite; for(pWrite=g.pWriteList; iFinal>0; pWrite=pWrite->pNext) iFinal--; pFinal = pWrite; } #ifdef TRACE_CRASHTEST printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a")); #endif ppPtr = &g.pWriteList; for(pWrite=*ppPtr; rc==SQLITE_OK && pWrite; pWrite=*ppPtr){ sqlite3_file *pRealFile = pWrite->pFile->pRealFile; /* (eAction==1) -> write block out normally, ** (eAction==2) -> do nothing, ** (eAction==3) -> trash sectors. */ int eAction = 0; if( !isCrash ){ eAction = 2; if( (pWrite->pFile==pFile || iDc&SQLITE_IOCAP_SEQUENTIAL) ){ eAction = 1; } }else{ char random; sqlite3_randomness(1, &random); /* Do not select option 3 (sector trashing) if the IOCAP_ATOMIC flag ** is set or this is an OsTruncate(), not an Oswrite(). */ if( (iDc&SQLITE_IOCAP_ATOMIC) || (pWrite->zBuf==0) ){ random &= 0x01; } /* If IOCAP_SEQUENTIAL is set and this is not the final entry ** in the truncated write-list, always select option 1 (write ** out correctly). */ if( (iDc&SQLITE_IOCAP_SEQUENTIAL && pWrite!=pFinal) ){ random = 0; } /* If IOCAP_SAFE_APPEND is set and this OsWrite() operation is ** an append (first byte of the written region is 1 byte past the ** current EOF), always select option 1 (write out correctly). */ if( iDc&SQLITE_IOCAP_SAFE_APPEND && pWrite->zBuf ){ i64 iSize; sqlite3OsFileSize(pRealFile, &iSize); if( iSize==pWrite->iOffset ){ random = 0; } } if( (random&0x06)==0x06 ){ eAction = 3; }else{ eAction = ((random&0x01)?2:1); } } switch( eAction ){ case 1: { /* Write out correctly */ if( pWrite->zBuf ){ rc = writeDbFile( pWrite->pFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset ); }else{ rc = sqlite3OsTruncate(pRealFile, pWrite->iOffset); } *ppPtr = pWrite->pNext; #ifdef TRACE_CRASHTEST if( isCrash ){ printf("Writing %d bytes @ %d (%s)\n", pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName ); } #endif crash_free(pWrite); break; } case 2: { /* Do nothing */ ppPtr = &pWrite->pNext; #ifdef TRACE_CRASHTEST if( isCrash ){ printf("Omiting %d bytes @ %d (%s)\n", pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName ); } #endif break; } case 3: { /* Trash sectors */ u8 *zGarbage; int iFirst = (int)(pWrite->iOffset/g.iSectorSize); int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize); assert(pWrite->zBuf); #ifdef TRACE_CRASHTEST printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName ); #endif zGarbage = crash_malloc(g.iSectorSize); if( zGarbage ){ sqlite3_int64 i; for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ sqlite3_randomness(g.iSectorSize, zGarbage); rc = writeDbFile( pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize ); } crash_free(zGarbage); }else{ rc = SQLITE_NOMEM; } ppPtr = &pWrite->pNext; break; } default: assert(!"Cannot happen"); } if( pWrite==pFinal ) break; } if( rc==SQLITE_OK && isCrash ){ exit(-1); } for(pWrite=g.pWriteList; pWrite && pWrite->pNext; pWrite=pWrite->pNext); g.pWriteListEnd = pWrite; return rc; }
/* ** This routine runs an extensive test of the Bitvec code. ** ** The input is an array of integers that acts as a program ** to test the Bitvec. The integers are opcodes followed ** by 0, 1, or 3 operands, depending on the opcode. Another ** opcode follows immediately after the last operand. ** ** There are 6 opcodes numbered from 0 through 5. 0 is the ** "halt" opcode and causes the test to end. ** ** 0 Halt and return the number of errors ** 1 N S X Set N bits beginning with S and incrementing by X ** 2 N S X Clear N bits beginning with S and incrementing by X ** 3 N Set N randomly chosen bits ** 4 N Clear N randomly chosen bits ** 5 N S X Set N bits from S increment X in array only, not in bitvec ** ** The opcodes 1 through 4 perform set and clear operations are performed ** on both a Bitvec object and on a linear array of bits obtained from malloc. ** Opcode 5 works on the linear array only, not on the Bitvec. ** Opcode 5 is used to deliberately induce a fault in order to ** confirm that error detection works. ** ** At the conclusion of the test the linear array is compared ** against the Bitvec object. If there are any differences, ** an error is returned. If they are the same, zero is returned. ** ** If a memory allocation error occurs, return -1. */ int sqlite3BitvecBuiltinTest(int sz, int *aOp){ Bitvec *pBitvec = 0; unsigned char *pV = 0; int rc = -1; int i, nx, pc, op; void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3MallocZero( (sz+7)/8 + 1 ); pTmpSpace = sqlite3_malloc(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; /* NULL pBitvec tests */ sqlite3BitvecSet(0, 1); sqlite3BitvecClear(0, 1, pTmpSpace); /* Run the program */ pc = 0; while( (op = aOp[pc])!=0 ){ switch( op ){ case 1: case 2: case 5: { nx = 4; i = aOp[pc+2] - 1; aOp[pc+2] += aOp[pc+3]; break; } case 3: case 4: default: { nx = 2; sqlite3_randomness(sizeof(i), &i); break; } } if( (--aOp[pc+1]) > 0 ) nx = 0; pc += nx; i = (i & 0x7fffffff)%sz; if( (op & 1)!=0 ){ SETBIT(pV, (i+1)); if( op!=5 ){ if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; } }else{ CLEARBIT(pV, (i+1)); sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); } } /* Test to make sure the linear array exactly matches the ** Bitvec object. Start with the assumption that they do ** match (rc==0). Change rc to non-zero if a discrepancy ** is found. */ rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + sqlite3BitvecTest(pBitvec, 0) + (sqlite3BitvecSize(pBitvec) - sz); for(i=1; i<=sz; i++){ if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ rc = i; break; } } /* Free allocated structure */ bitvec_end: sqlite3_free(pTmpSpace); sqlite3_free(pV); sqlite3BitvecDestroy(pBitvec); return rc; }
/* Return a pseudo-random integer between 0 and N-1 */ static int randint(int N){ unsigned char x; assert( N<256 ); sqlite3_randomness(1, &x); return x % N; }
static int interpolate (chirp_jobid_t id, char task_path[CHIRP_PATH_MAX], char serv_path[CHIRP_PATH_MAX]) { int rc; char *mark; for (mark = serv_path; (mark = strchr(mark, '%')); ) { switch (mark[1]) { case 'g': case 'h': case 's': { /* replace with hash of task_path */ unsigned char digest[SHA1_DIGEST_LENGTH]; if (mark[1] == 'h') CATCHUNIX(sha1_file(task_path, digest) ? 0 : -1); else if (mark[1] == 'g') sqlite3_randomness(SHA1_DIGEST_LENGTH, digest); else if (mark[1] == 's') { struct stat64 buf; CATCHUNIX(stat64(task_path, &buf)); if (buf.st_size <= MAX_SIZE_HASH) { CATCHUNIX(sha1_file(task_path, digest) ? 0 : -1); } else { sqlite3_randomness(SHA1_DIGEST_LENGTH, digest); } } if (strlen(serv_path)+sizeof(digest)*2 < CHIRP_PATH_MAX) { size_t i; memmove(mark+sizeof(digest)*2, mark+2, strlen(mark+2)+1); for (i = 0; i < sizeof(digest); i++) { char hex[3]; CATCHUNIX(snprintf(hex, sizeof(hex), "%02X", (unsigned int)digest[i])); assert(rc == 2); mark[i*2] = hex[0]; mark[i*2+1] = hex[1]; } mark += sizeof(digest)*2; } else { CATCH(ENAMETOOLONG); } break; } case 'j': { char str[64]; CATCHUNIX(snprintf(str, sizeof(str), "%" PRICHIRP_JOBID_T, id)); assert((size_t)rc < sizeof(str)); if (strlen(serv_path)+strlen(str) < CHIRP_PATH_MAX) { memmove(mark+strlen(str), mark+2, strlen(mark+2)+1); memcpy(mark, str, strlen(str)); mark += strlen(str); } else { CATCH(ENAMETOOLONG); } break; } default: mark += 1; /* ignore */ break; } } rc = 0; goto out; out: return rc; }
DLL_FUNCTION(void) BU_SQLite_Randomness(int32_t n, void* p) { #pragma comment(linker, "/EXPORT:BU_SQLite_Randomness=_BU_SQLite_Randomness@8") sqlite3_randomness(n, p); }
/* ** Report on the vocabulary. This creates an fts4aux table with a random ** name, but deletes it in the end. */ static void showVocabulary(sqlite3 *db, const char *zTab) { char *zAux; sqlite3_uint64 r; sqlite3_stmt *pStmt; int nDoc = 0; int nToken = 0; int nOccurrence = 0; int nTop; int n, i; sqlite3_randomness(sizeof(r), &r); zAux = sqlite3_mprintf("viewer_%llx", zTab, r); runSql(db, "BEGIN"); pStmt = prepare(db, "SELECT count(*) FROM %Q", zTab); while( sqlite3_step(pStmt)==SQLITE_ROW ) { nDoc = sqlite3_column_int(pStmt, 0); } sqlite3_finalize(pStmt); printf("Number of documents...................... %9d\n", nDoc); runSql(db, "CREATE VIRTUAL TABLE %s USING fts4aux(%Q)", zAux, zTab); pStmt = prepare(db, "SELECT count(*), sum(occurrences) FROM %s WHERE col='*'", zAux); while( sqlite3_step(pStmt)==SQLITE_ROW ) { nToken = sqlite3_column_int(pStmt, 0); nOccurrence = sqlite3_column_int(pStmt, 1); } sqlite3_finalize(pStmt); printf("Total tokens in all documents............ %9d\n", nOccurrence); printf("Total number of distinct tokens.......... %9d\n", nToken); if( nToken==0 ) goto end_vocab; n = 0; pStmt = prepare(db, "SELECT count(*) FROM %s" " WHERE col='*' AND occurrences==1", zAux); while( sqlite3_step(pStmt)==SQLITE_ROW ) { n = sqlite3_column_int(pStmt, 0); } sqlite3_finalize(pStmt); printf("Tokens used exactly once................. %9d %5.2f%%\n", n, n*100.0/nToken); n = 0; pStmt = prepare(db, "SELECT count(*) FROM %s" " WHERE col='*' AND documents==1", zAux); while( sqlite3_step(pStmt)==SQLITE_ROW ) { n = sqlite3_column_int(pStmt, 0); } sqlite3_finalize(pStmt); printf("Tokens used in only one document......... %9d %5.2f%%\n", n, n*100.0/nToken); if( nDoc>=2000 ) { n = 0; pStmt = prepare(db, "SELECT count(*) FROM %s" " WHERE col='*' AND occurrences<=%d", zAux, nDoc/1000); while( sqlite3_step(pStmt)==SQLITE_ROW ) { n = sqlite3_column_int(pStmt, 0); } sqlite3_finalize(pStmt); printf("Tokens used in 0.1%% or less of docs...... %9d %5.2f%%\n", n, n*100.0/nToken); } if( nDoc>=200 ) { n = 0; pStmt = prepare(db, "SELECT count(*) FROM %s" " WHERE col='*' AND occurrences<=%d", zAux, nDoc/100); while( sqlite3_step(pStmt)==SQLITE_ROW ) { n = sqlite3_column_int(pStmt, 0); } sqlite3_finalize(pStmt); printf("Tokens used in 1%% or less of docs........ %9d %5.2f%%\n", n, n*100.0/nToken); } nTop = atoi(findOption("top", 1, "25")); printf("The %d most common tokens:\n", nTop); pStmt = prepare(db, "SELECT term, documents FROM %s" " WHERE col='*'" " ORDER BY documents DESC, term" " LIMIT %d", zAux, nTop); i = 0; while( sqlite3_step(pStmt)==SQLITE_ROW ) { i++; n = sqlite3_column_int(pStmt, 1); printf(" %2d. %-30s %9d docs %5.2f%%\n", i, sqlite3_column_text(pStmt, 0), n, n*100.0/nDoc); } sqlite3_finalize(pStmt); end_vocab: runSql(db, "ROLLBACK"); sqlite3_free(zAux); }