/ Check-in [674de36b]
Login

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

Overview
Comment:Furhter cleanup of the winGetTempname function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | win32heap
Files: files | file ages | folders
SHA1: 674de36bcaafc1130b7603e69616c71fc8cd7de7
User & Date: mistachkin 2013-11-09 21:10:47
Context
2013-11-09
21:11
Use the UNICODE_STRING_MAX_CHARS constant from WinNT.h. Closed-Leaf check-in: 3fefe4dd user: mistachkin tags: win32heap
21:10
Furhter cleanup of the winGetTempname function. check-in: 674de36b user: mistachkin tags: win32heap
2013-11-08
20:10
Add more assert() statements and fix compilation issues when the Win32 native heap is not enabled. check-in: fbf8c382 user: mistachkin tags: win32heap
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/os_win.c.

  4122   4122   */
  4123   4123   static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
  4124   4124     static char zChars[] =
  4125   4125       "abcdefghijklmnopqrstuvwxyz"
  4126   4126       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4127   4127       "0123456789";
  4128   4128     size_t i, j;
  4129         -  int nBuf, nLen;
         4129  +  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
         4130  +  int nMax, nBuf, nDir, nLen;
  4130   4131     char *zBuf;
  4131   4132   
  4132   4133     /* It's odd to simulate an io-error here, but really this is just
  4133   4134     ** using the io-error infrastructure to test that SQLite handles this
  4134   4135     ** function failing. 
  4135   4136     */
  4136   4137     SimulateIOError( return SQLITE_IOERR );
  4137   4138   
  4138   4139     /* Allocate a temporary buffer to store the fully qualified file
  4139   4140     ** name for the temporary file.  If this fails, we cannot continue.
  4140   4141     */
  4141         -  nBuf = pVfs->mxPathname;
  4142         -  zBuf = sqlite3MallocZero( nBuf+3 );
         4142  +  nMax = pVfs->mxPathname; nBuf = nMax + 2;
         4143  +  zBuf = sqlite3MallocZero( nBuf );
  4143   4144     if( !zBuf ){
  4144   4145       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4145   4146       return SQLITE_IOERR_NOMEM;
  4146   4147     }
  4147   4148   
  4148   4149     /* Figure out the effective temporary directory.  First, check if one
  4149   4150     ** has been explicitly set by the application; otherwise, use the one
  4150   4151     ** configured by the operating system.
  4151   4152     */
  4152         -  assert( nBuf>30 );
         4153  +  nDir = nMax - (nPre + 15);
         4154  +  assert( nDir>0 );
  4153   4155     if( sqlite3_temp_directory ){
  4154         -    sqlite3_snprintf(nBuf-30, zBuf, "%s", sqlite3_temp_directory);
  4155         -    winMakeEndInDirSep(nBuf-30, zBuf);
         4156  +    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
         4157  +    if( nDirLen>0 ){
         4158  +      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
         4159  +        nDirLen++;
         4160  +      }
         4161  +      if( nDirLen>nDir ){
         4162  +        sqlite3_free(zBuf);
         4163  +        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
         4164  +        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
         4165  +      }
         4166  +      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
         4167  +    }
  4156   4168     }
  4157   4169   #if defined(__CYGWIN__)
  4158   4170     else{
  4159   4171       static const char *azDirs[] = {
  4160   4172          0, /* getenv("SQLITE_TMPDIR") */
  4161   4173          0, /* getenv("TMPDIR") */
  4162   4174          0, /* getenv("TMP") */
................................................................................
  4188   4200           zConverted = winConvertFromUtf8Filename(zDir);
  4189   4201           if( !zConverted ){
  4190   4202             sqlite3_free(zBuf);
  4191   4203             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4192   4204             return SQLITE_IOERR_NOMEM;
  4193   4205           }
  4194   4206           if( winIsDir(zConverted) ){
  4195         -          sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
  4196         -          winMakeEndInDirSep(nBuf-30, zBuf);
         4207  +          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
  4197   4208             sqlite3_free(zConverted);
  4198   4209             break;
  4199   4210           }
  4200   4211           sqlite3_free(zConverted);
  4201   4212         }else{
  4202         -        zConverted = sqlite3MallocZero( nBuf+1 );
         4213  +        zConverted = sqlite3MallocZero( nMax+1 );
  4203   4214           if( !zConverted ){
  4204   4215             sqlite3_free(zBuf);
  4205   4216             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4206   4217             return SQLITE_IOERR_NOMEM;
  4207   4218           }
  4208   4219           if( cygwin_conv_path(
  4209   4220                   osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
  4210         -                zConverted, nBuf+1)<0 ){
         4221  +                zConverted, nMax+1)<0 ){
  4211   4222             sqlite3_free(zConverted);
  4212   4223             sqlite3_free(zBuf);
  4213   4224             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
  4214   4225             return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
  4215         -                             "winGetTempname1", zDir);
         4226  +                             "winGetTempname2", zDir);
  4216   4227           }
  4217   4228           if( winIsDir(zConverted) ){
  4218   4229             /* At this point, we know the candidate directory exists and should
  4219   4230             ** be used.  However, we may need to convert the string containing
  4220   4231             ** its name into UTF-8 (i.e. if it is UTF-16 right now).
  4221   4232             */
  4222   4233             if( osIsNT() ){
................................................................................
  4223   4234               char *zUtf8 = winUnicodeToUtf8(zConverted);
  4224   4235               if( !zUtf8 ){
  4225   4236                 sqlite3_free(zConverted);
  4226   4237                 sqlite3_free(zBuf);
  4227   4238                 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4228   4239                 return SQLITE_IOERR_NOMEM;
  4229   4240               }
  4230         -            sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
  4231         -            winMakeEndInDirSep(nBuf-30, zBuf);
         4241  +            sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
  4232   4242               sqlite3_free(zUtf8);
  4233   4243               sqlite3_free(zConverted);
  4234   4244               break;
  4235   4245             }else{
  4236         -            sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
  4237         -            winMakeEndInDirSep(nBuf-30, zBuf);
         4246  +            sqlite3_snprintf(nMax, zBuf, "%s", zConverted);
  4238   4247               sqlite3_free(zConverted);
  4239   4248               break;
  4240   4249             }
  4241   4250           }
  4242   4251           sqlite3_free(zConverted);
  4243   4252         }
  4244   4253       }
  4245   4254     }
  4246   4255   #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  4247   4256     else if( osIsNT() ){
  4248   4257       char *zMulti;
  4249         -    LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) );
         4258  +    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
  4250   4259       if( !zWidePath ){
  4251   4260         sqlite3_free(zBuf);
  4252   4261         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4253   4262         return SQLITE_IOERR_NOMEM;
  4254   4263       }
  4255         -    if( osGetTempPathW(nBuf, zWidePath)==0 ){
         4264  +    if( osGetTempPathW(nMax, zWidePath)==0 ){
  4256   4265         sqlite3_free(zWidePath);
  4257   4266         sqlite3_free(zBuf);
  4258   4267         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4259   4268         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4260         -                         "winGetTempname1", 0);
         4269  +                         "winGetTempname2", 0);
  4261   4270       }
  4262   4271       zMulti = winUnicodeToUtf8(zWidePath);
  4263   4272       if( zMulti ){
  4264         -      sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti);
  4265         -      winMakeEndInDirSep(nBuf-30, zBuf);
         4273  +      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
  4266   4274         sqlite3_free(zMulti);
  4267   4275         sqlite3_free(zWidePath);
  4268   4276       }else{
  4269   4277         sqlite3_free(zWidePath);
  4270   4278         sqlite3_free(zBuf);
  4271   4279         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4272   4280         return SQLITE_IOERR_NOMEM;
  4273   4281       }
  4274   4282     }
  4275   4283   #ifdef SQLITE_WIN32_HAS_ANSI
  4276   4284     else{
  4277   4285       char *zUtf8;
  4278         -    char *zMbcsPath = sqlite3MallocZero( nBuf );
         4286  +    char *zMbcsPath = sqlite3MallocZero( nMax );
  4279   4287       if( !zMbcsPath ){
  4280   4288         sqlite3_free(zBuf);
  4281   4289         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4282   4290         return SQLITE_IOERR_NOMEM;
  4283   4291       }
  4284         -    if( osGetTempPathA(nBuf, zMbcsPath)==0 ){
         4292  +    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
  4285   4293         sqlite3_free(zBuf);
  4286   4294         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4287   4295         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4288         -                         "winGetTempname2", 0);
         4296  +                         "winGetTempname3", 0);
  4289   4297       }
  4290   4298       zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
  4291   4299       if( zUtf8 ){
  4292         -      sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
  4293         -      winMakeEndInDirSep(nBuf-30, zBuf);
         4300  +      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
  4294   4301         sqlite3_free(zUtf8);
  4295   4302       }else{
  4296   4303         sqlite3_free(zBuf);
  4297   4304         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4298   4305         return SQLITE_IOERR_NOMEM;
  4299   4306       }
  4300   4307     }
  4301   4308   #endif /* SQLITE_WIN32_HAS_ANSI */
  4302   4309   #endif /* !SQLITE_OS_WINRT */
  4303   4310   
  4304         -  /* Check that the output buffer is large enough for the temporary file 
  4305         -  ** name. If it is not, return SQLITE_ERROR.
         4311  +  /*
         4312  +  ** Check to make sure the temporary directory ends with an appropriate
         4313  +  ** separator.  If it does not and there is not enough space left to add
         4314  +  ** one, fail.
         4315  +  */
         4316  +  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
         4317  +    sqlite3_free(zBuf);
         4318  +    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
         4319  +    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
         4320  +  }
         4321  +
         4322  +  /*
         4323  +  ** Check that the output buffer is large enough for the temporary file 
         4324  +  ** name in the following format:
         4325  +  **
         4326  +  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
         4327  +  **
         4328  +  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
         4329  +  ** account for the space used by the 15 character random suffix and the
         4330  +  ** two trailing NUL characters.  The final directory separator character
         4331  +  ** has already added if it was not already present.
  4306   4332     */
  4307   4333     nLen = sqlite3Strlen30(zBuf);
  4308         -
  4309         -  if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
         4334  +  if( (nLen + nPre + 17) > nBuf ){
  4310   4335       sqlite3_free(zBuf);
  4311   4336       OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
  4312         -    return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0);
         4337  +    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
  4313   4338     }
  4314   4339   
  4315         -  sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
         4340  +  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
  4316   4341   
  4317   4342     j = sqlite3Strlen30(zBuf);
  4318   4343     sqlite3_randomness(15, &zBuf[j]);
  4319   4344     for(i=0; i<15; i++, j++){
  4320   4345       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  4321   4346     }
  4322   4347     zBuf[j] = 0;