/ Check-in [f2bdccf4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Refactor the interface to the randomness generator. (CVS 1224)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f2bdccf4bb2f796aafb64c33e55f62a1794d750c
User & Date: drh 2004-02-11 09:46:31
Context
2004-02-11
10:35
Fix an uninitialized variable in expr.c. Ticket #604. (CVS 1225) check-in: 1673bf7c user: drh tags: trunk
09:46
Refactor the interface to the randomness generator. (CVS 1224) check-in: f2bdccf4 user: drh tags: trunk
02:18
Pass all (relevant) regression tests when using the codec. (CVS 1223) check-in: 5200e9ed user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.164 2004/01/19 04:55:56 jplyon Exp $
           26  +** $Id: build.c,v 1.165 2004/02/11 09:46:31 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
   815    815   ** the schema to change multiple times and for the cookie to be
   816    816   ** set back to prior value.  But schema changes are infrequent
   817    817   ** and the probability of hitting the same cookie value is only
   818    818   ** 1 chance in 2^32.  So we're safe enough.
   819    819   */
   820    820   void sqliteChangeCookie(sqlite *db, Vdbe *v){
   821    821     if( db->next_cookie==db->aDb[0].schema_cookie ){
   822         -    db->next_cookie = db->aDb[0].schema_cookie + sqliteRandomByte() + 1;
          822  +    unsigned char r;
          823  +    sqliteRandomness(1, &r);
          824  +    db->next_cookie = db->aDb[0].schema_cookie + r + 1;
   823    825       db->flags |= SQLITE_InternChanges;
   824    826       sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
   825    827       sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
   826    828     }
   827    829   }
   828    830   
   829    831   /*

Changes to src/func.c.

    12     12   ** This file contains the C functions that implement various SQL
    13     13   ** functions of SQLite.  
    14     14   **
    15     15   ** There is only one exported symbol in this file - the function
    16     16   ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
    17     17   ** All other code has file scope.
    18     18   **
    19         -** $Id: func.c,v 1.38 2004/01/30 14:49:17 drh Exp $
           19  +** $Id: func.c,v 1.39 2004/02/11 09:46:32 drh Exp $
    20     20   */
    21     21   #include <ctype.h>
    22     22   #include <math.h>
    23     23   #include <stdlib.h>
    24     24   #include <assert.h>
    25     25   #include "sqliteInt.h"
    26     26   #include "os.h"
................................................................................
   191    191     }
   192    192   }
   193    193   
   194    194   /*
   195    195   ** Implementation of random().  Return a random integer.  
   196    196   */
   197    197   static void randomFunc(sqlite_func *context, int argc, const char **argv){
   198         -  sqlite_set_result_int(context, sqliteRandomInteger());
          198  +  int r;
          199  +  sqliteRandomness(sizeof(r), &r);
          200  +  sqlite_set_result_int(context, r);
   199    201   }
   200    202   
   201    203   /*
   202    204   ** Implementation of the last_insert_rowid() SQL function.  The return
   203    205   ** value is the same as the sqlite_last_insert_rowid() API function.
   204    206   */
   205    207   static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){
................................................................................
   337    339   
   338    340   #ifdef SQLITE_TEST
   339    341   /*
   340    342   ** This function generates a string of random characters.  Used for
   341    343   ** generating test data.
   342    344   */
   343    345   static void randStr(sqlite_func *context, int argc, const char **argv){
   344         -  static const char zSrc[] = 
          346  +  static const unsigned char zSrc[] = 
   345    347        "abcdefghijklmnopqrstuvwxyz"
   346    348        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   347    349        "0123456789"
   348    350        ".-!,:*^+=_|?/<> ";
   349    351     int iMin, iMax, n, r, i;
   350         -  char zBuf[1000];
          352  +  unsigned char zBuf[1000];
   351    353     if( argc>=1 ){
   352    354       iMin = atoi(argv[0]);
   353    355       if( iMin<0 ) iMin = 0;
   354    356       if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
   355    357     }else{
   356    358       iMin = 1;
   357    359     }
................................................................................
   360    362       if( iMax<iMin ) iMax = iMin;
   361    363       if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
   362    364     }else{
   363    365       iMax = 50;
   364    366     }
   365    367     n = iMin;
   366    368     if( iMax>iMin ){
   367         -    r = sqliteRandomInteger() & 0x7fffffff;
          369  +    sqliteRandomness(sizeof(r), &r);
          370  +    r &= 0x7fffffff;
   368    371       n += r%(iMax + 1 - iMin);
   369    372     }
   370    373     assert( n<sizeof(zBuf) );
   371         -  r = 0;
          374  +  sqliteRandomness(n, zBuf);
   372    375     for(i=0; i<n; i++){
   373         -    r = (r + sqliteRandomByte())% (sizeof(zSrc)-1);
   374         -    zBuf[i] = zSrc[r];
          376  +    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
   375    377     }
   376    378     zBuf[n] = 0;
   377    379     sqlite_set_result_string(context, zBuf, n);
   378    380   }
   379    381   #endif
   380    382   
   381    383   /*

Changes to src/os.c.

   781    781   #if OS_UNIX
   782    782     static const char *azDirs[] = {
   783    783        "/var/tmp",
   784    784        "/usr/tmp",
   785    785        "/tmp",
   786    786        ".",
   787    787     };
   788         -  static char zChars[] =
          788  +  static unsigned char zChars[] =
   789    789       "abcdefghijklmnopqrstuvwxyz"
   790    790       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   791    791       "0123456789";
   792    792     int i, j;
   793    793     struct stat buf;
   794    794     const char *zDir = ".";
   795    795     for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
................................................................................
   798    798       if( access(azDirs[i], 07) ) continue;
   799    799       zDir = azDirs[i];
   800    800       break;
   801    801     }
   802    802     do{
   803    803       sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
   804    804       j = strlen(zBuf);
   805         -    for(i=0; i<15; i++){
   806         -      int n = sqliteRandomByte() % (sizeof(zChars)-1);
   807         -      zBuf[j++] = zChars[n];
          805  +    sqliteRandomness(15, &zBuf[j]);
          806  +    for(i=0; i<15; i++, j++){
          807  +      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   808    808       }
   809    809       zBuf[j] = 0;
   810    810     }while( access(zBuf,0)==0 );
   811    811   #endif
   812    812   #if OS_WIN
   813    813     static char zChars[] =
   814    814       "abcdefghijklmnopqrstuvwxyz"
................................................................................
   818    818     char zTempPath[SQLITE_TEMPNAME_SIZE];
   819    819     GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
   820    820     for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
   821    821     zTempPath[i] = 0;
   822    822     for(;;){
   823    823       sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
   824    824       j = strlen(zBuf);
   825         -    for(i=0; i<15; i++){
   826         -      int n = sqliteRandomByte() % (sizeof(zChars) - 1);
   827         -      zBuf[j++] = zChars[n];
          825  +    sqliteRandomness(15, &zBuf[j]);
          826  +    for(i=0; i<15; i++, j++){
          827  +      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   828    828       }
   829    829       zBuf[j] = 0;
   830    830       if( !sqliteOsFileExists(zBuf) ) break;
   831    831     }
   832    832   #endif
   833    833   #if OS_MAC
   834    834     static char zChars[] =
................................................................................
   861    861       } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
   862    862     }
   863    863     if( *zTempPath == 0 )
   864    864       getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
   865    865     for(;;){
   866    866       sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
   867    867       j = strlen(zBuf);
   868         -    for(i=0; i<15; i++){
   869         -      int n = sqliteRandomByte() % sizeof(zChars);
   870         -      zBuf[j++] = zChars[n];
          868  +    sqliteRandomness(15, &zBuf[j]);
          869  +    for(i=0; i<15; i++, j++){
          870  +      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   871    871       }
   872    872       zBuf[j] = 0;
   873    873       if( !sqliteOsFileExists(zBuf) ) break;
   874    874     }
   875    875   #endif
   876    876     return SQLITE_OK; 
   877    877   }
................................................................................
  1321   1321     return rc;
  1322   1322   #endif
  1323   1323   #if OS_WIN
  1324   1324     int rc;
  1325   1325     if( id->locked>0 ){
  1326   1326       rc = SQLITE_OK;
  1327   1327     }else{
  1328         -    int lk = (sqliteRandomInteger() & 0x7ffffff)%N_LOCKBYTE+1;
         1328  +    int lk;
  1329   1329       int res;
  1330   1330       int cnt = 100;
         1331  +    sqliteRandomness(sizeof(lk), &lk);
         1332  +    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
  1331   1333       while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
  1332   1334         Sleep(1);
  1333   1335       }
  1334   1336       if( res ){
  1335   1337         UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
  1336   1338         if( isNT() ){
  1337   1339           OVERLAPPED ovlp;
................................................................................
  1355   1357     return rc;
  1356   1358   #endif
  1357   1359   #if OS_MAC
  1358   1360     int rc;
  1359   1361     if( id->locked>0 || id->refNumRF == -1 ){
  1360   1362       rc = SQLITE_OK;
  1361   1363     }else{
  1362         -    int lk = (sqliteRandomInteger() & 0x7ffffff)%N_LOCKBYTE+1;
         1364  +    int lk;
  1363   1365       OSErr res;
  1364   1366       int cnt = 5;
  1365   1367       ParamBlockRec params;
         1368  +    sqliteRandomness(sizeof(lk), &lk);
         1369  +    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
  1366   1370       memset(&params, 0, sizeof(params));
  1367   1371       params.ioParam.ioRefNum = id->refNumRF;
  1368   1372       params.ioParam.ioPosMode = fsFromStart;
  1369   1373       params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
  1370   1374       params.ioParam.ioReqCount = 1;
  1371   1375       while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
  1372   1376         UInt32 finalTicks;

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.99 2004/02/11 02:18:07 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.100 2004/02/11 09:46:32 drh Exp $
    22     22   */
    23     23   #include "os.h"         /* Must be first to enable large file support */
    24     24   #include "sqliteInt.h"
    25     25   #include "pager.h"
    26     26   #include <assert.h>
    27     27   #include <string.h>
    28     28   
................................................................................
  1660   1660     pPager->origDbSize = pPager->dbSize;
  1661   1661     if( journal_format==JOURNAL_FORMAT_3 ){
  1662   1662       rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3));
  1663   1663       if( rc==SQLITE_OK ){
  1664   1664         rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
  1665   1665       }
  1666   1666       if( rc==SQLITE_OK ){
  1667         -      pPager->cksumInit = (u32)sqliteRandomInteger();
         1667  +      sqliteRandomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
  1668   1668         rc = write32bits(&pPager->jfd, pPager->cksumInit);
  1669   1669       }
  1670   1670     }else if( journal_format==JOURNAL_FORMAT_2 ){
  1671   1671       rc = sqliteOsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2));
  1672   1672     }else{
  1673   1673       assert( journal_format==JOURNAL_FORMAT_1 );
  1674   1674       rc = sqliteOsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1));

Changes to src/random.c.

    11     11   *************************************************************************
    12     12   ** This file contains code to implement a pseudo-random number
    13     13   ** generator (PRNG) for SQLite.
    14     14   **
    15     15   ** Random numbers are used by some of the database backends in order
    16     16   ** to generate random integer keys for tables or random filenames.
    17     17   **
    18         -** $Id: random.c,v 1.10 2002/02/19 13:39:23 drh Exp $
           18  +** $Id: random.c,v 1.11 2004/02/11 09:46:33 drh Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   #include "os.h"
    22     22   
    23     23   
    24     24   /*
    25     25   ** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
................................................................................
    31     31   ** well be good enough.  But maybe not.  Or maybe lrand48() has some
    32     32   ** subtle problems on some systems that could cause problems.  It is hard
    33     33   ** to know.  To minimize the risk of problems due to bad lrand48()
    34     34   ** implementations, SQLite uses this random number generator based
    35     35   ** on RC4, which we know works very well.
    36     36   */
    37     37   static int randomByte(){
    38         -  int t;
           38  +  unsigned char t;
    39     39   
    40     40     /* All threads share a single random number generator.
    41     41     ** This structure is the current state of the generator.
    42     42     */
    43     43     static struct {
    44         -    int isInit;          /* True if initialized */
    45         -    int i, j;            /* State variables */
    46         -    int s[256];          /* State variables */
           44  +    unsigned char isInit;          /* True if initialized */
           45  +    unsigned char i, j;            /* State variables */
           46  +    unsigned char s[256];          /* State variables */
    47     47     } prng;
    48     48   
    49     49     /* Initialize the state of the random number generator once,
    50     50     ** the first time this routine is called.  The seed value does
    51     51     ** not need to contain a lot of randomness since we are not
    52     52     ** trying to do secure encryption or anything like that...
    53     53     **
................................................................................
    61     61       prng.j = 0;
    62     62       prng.i = 0;
    63     63       sqliteOsRandomSeed(k);
    64     64       for(i=0; i<256; i++){
    65     65         prng.s[i] = i;
    66     66       }
    67     67       for(i=0; i<256; i++){
    68         -      int t;
    69         -      prng.j = (prng.j + prng.s[i] + k[i]) & 0xff;
           68  +      prng.j += prng.s[i] + k[i];
    70     69         t = prng.s[prng.j];
    71     70         prng.s[prng.j] = prng.s[i];
    72     71         prng.s[i] = t;
    73     72       }
    74     73       prng.isInit = 1;
    75     74     }
    76     75   
    77     76     /* Generate and return single random byte
    78     77     */
    79         -  prng.i = (prng.i + 1) & 0xff;
    80         -  prng.j = (prng.j + prng.s[prng.i]) & 0xff;
           78  +  prng.i++;
    81     79     t = prng.s[prng.i];
           80  +  prng.j += t;
    82     81     prng.s[prng.i] = prng.s[prng.j];
    83     82     prng.s[prng.j] = t;
    84         -  t = prng.s[prng.i] + prng.s[prng.j];
    85         -  return prng.s[t & 0xff];
           83  +  t += prng.s[prng.i];
           84  +  return prng.s[t];
    86     85   }
    87     86   
    88     87   /*
    89         -** Return an random 8-bit integer.
           88  +** Return N random bytes.
    90     89   */
    91         -int sqliteRandomByte(){
    92         -  int r;
           90  +void sqliteRandomness(int N, void *pBuf){
           91  +  unsigned char *zBuf = pBuf;
    93     92     sqliteOsEnterMutex();
    94         -  r = randomByte();
    95         -  sqliteOsLeaveMutex();
    96         -  return r;
    97         -}
    98         -
    99         -/*
   100         -** Return a random 32-bit integer.  The integer is generated by making
   101         -** 4 calls to sqliteRandomByte().
   102         -*/
   103         -int sqliteRandomInteger(){
   104         -  int r;
   105         -  int i;
   106         -  sqliteOsEnterMutex();
   107         -  r = randomByte();
   108         -  for(i=1; i<4; i++){
   109         -    r = (r<<8) + randomByte();
           93  +  while( N-- ){
           94  +    *(zBuf++) = randomByte();
   110     95     }
   111     96     sqliteOsLeaveMutex();
   112         -  return r;
   113     97   }

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.209 2004/01/16 15:55:38 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.210 2004/02/11 09:46:33 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "vdbe.h"
    20     20   #include "parse.h"
    21     21   #include "btree.h"
................................................................................
  1147   1147   int sqliteExprCheck(Parse*, Expr*, int, int*);
  1148   1148   int sqliteExprType(Expr*);
  1149   1149   int sqliteExprCompare(Expr*, Expr*);
  1150   1150   int sqliteFuncId(Token*);
  1151   1151   int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
  1152   1152   int sqliteExprAnalyzeAggregates(Parse*, Expr*);
  1153   1153   Vdbe *sqliteGetVdbe(Parse*);
  1154         -int sqliteRandomByte(void);
  1155         -int sqliteRandomInteger(void);
         1154  +void sqliteRandomness(int, void*);
  1156   1155   void sqliteRollbackAll(sqlite*);
  1157   1156   void sqliteCodeVerifySchema(Parse*, int);
  1158   1157   void sqliteBeginTransaction(Parse*, int);
  1159   1158   void sqliteCommitTransaction(Parse*);
  1160   1159   void sqliteRollbackTransaction(Parse*);
  1161   1160   int sqliteExprIsConstant(Expr*);
  1162   1161   int sqliteExprIsInteger(Expr*, int*);

Changes to src/vacuum.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the VACUUM command.
    13     13   **
    14     14   ** Most of the code in this file may be omitted by defining the
    15     15   ** SQLITE_OMIT_VACUUM macro.
    16     16   **
    17         -** $Id: vacuum.c,v 1.9 2003/12/07 00:24:35 drh Exp $
           17  +** $Id: vacuum.c,v 1.10 2004/02/11 09:46:33 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   
    22     22   /*
    23     23   ** A structure for holding a dynamic string - a string that can grow
    24     24   ** without bound. 
................................................................................
   181    181     rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
   182    182     return rc;
   183    183   }
   184    184   
   185    185   /*
   186    186   ** Generate a random name of 20 character in length.
   187    187   */
   188         -static void randomName(char *zBuf){
   189         -  static const char zChars[] =
          188  +static void randomName(unsigned char *zBuf){
          189  +  static const unsigned char zChars[] =
   190    190       "abcdefghijklmnopqrstuvwxyz"
   191    191       "0123456789";
   192    192     int i;
          193  +  sqliteRandomness(20, zBuf);
   193    194     for(i=0; i<20; i++){
   194         -    int n = sqliteRandomByte() % (sizeof(zChars)-1);
   195         -    zBuf[i] = zChars[n];
          195  +    zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
   196    196     }
   197    197   }
   198    198   #endif
   199    199   
   200    200   /*
   201    201   ** The non-standard VACUUM command is used to clean up the database,
   202    202   ** collapse free space, etc.  It is modelled after the VACUUM command

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.258 2004/02/10 13:41:52 drh Exp $
           46  +** $Id: vdbe.c,v 1.259 2004/02/11 09:46:33 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  2889   2889         }
  2890   2890       }
  2891   2891       if( pC->useRandomRowid ){
  2892   2892         v = db->priorNewRowid;
  2893   2893         cnt = 0;
  2894   2894         do{
  2895   2895           if( v==0 || cnt>2 ){
  2896         -          v = sqliteRandomInteger();
         2896  +          sqliteRandomness(sizeof(v), &v);
  2897   2897             if( cnt<5 ) v &= 0xffffff;
  2898   2898           }else{
  2899         -          v += sqliteRandomByte() + 1;
         2899  +          unsigned char r;
         2900  +          sqliteRandomness(1, &r);
         2901  +          v += r + 1;
  2900   2902           }
  2901   2903           if( v==0 ) continue;
  2902   2904           x = intToKey(v);
  2903   2905           rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
  2904   2906           cnt++;
  2905   2907         }while( cnt<1000 && rx==SQLITE_OK && res==0 );
  2906   2908         db->priorNewRowid = v;