/ Check-in [d99bb0c1]
Login

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

Overview
Comment:Avoid reading outside a record buffer when extracting an SQL value in the sqlite_dbdata virtual table code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25
User & Date: dan 2019-05-09 11:34:31
Context
2019-05-09
11:45
Fix a problem with running the ".recover" command on a database that is zero pages in size. check-in: 47fa6534 user: dan tags: trunk
11:34
Avoid reading outside a record buffer when extracting an SQL value in the sqlite_dbdata virtual table code. check-in: d99bb0c1 user: dan tags: trunk
11:21
Merge accidental fork in trunk. check-in: ec937303 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/dbdata.c.

   378    378         return 4;
   379    379       case 5:
   380    380         return 6;
   381    381       case 6:
   382    382       case 7:
   383    383         return 8;
   384    384       default:
   385         -      return ((eType-12) / 2);
          385  +      if( eType>0 ){
          386  +        return ((eType-12) / 2);
          387  +      }
          388  +      return 0;
   386    389     }
   387    390   }
   388    391   
   389    392   /*
   390    393   ** Load a value of type eType from buffer pData and use it to set the
   391    394   ** result of context object pCtx.
   392    395   */
   393         -static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){
   394         -  switch( eType ){
   395         -    case 0: 
   396         -    case 10: 
   397         -    case 11: 
   398         -      sqlite3_result_null(pCtx);
   399         -      break;
   400         -    
   401         -    case 8: 
   402         -      sqlite3_result_int(pCtx, 0);
   403         -      break;
   404         -    case 9:
   405         -      sqlite3_result_int(pCtx, 1);
   406         -      break;
   407         -
   408         -    case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
   409         -      sqlite3_uint64 v = (signed char)pData[0];
   410         -      pData++;
   411         -      switch( eType ){
   412         -        case 7:
   413         -        case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
   414         -        case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
   415         -        case 4:  v = (v<<8) + pData[0];  pData++;
   416         -        case 3:  v = (v<<8) + pData[0];  pData++;
   417         -        case 2:  v = (v<<8) + pData[0];  pData++;
          396  +static void dbdataValue(
          397  +  sqlite3_context *pCtx, 
          398  +  int eType, 
          399  +  u8 *pData,
          400  +  int nData
          401  +){
          402  +  if( eType>=0 && dbdataValueBytes(eType)<=nData ){
          403  +    switch( eType ){
          404  +      case 0: 
          405  +      case 10: 
          406  +      case 11: 
          407  +        sqlite3_result_null(pCtx);
          408  +        break;
          409  +      
          410  +      case 8: 
          411  +        sqlite3_result_int(pCtx, 0);
          412  +        break;
          413  +      case 9:
          414  +        sqlite3_result_int(pCtx, 1);
          415  +        break;
          416  +  
          417  +      case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
          418  +        sqlite3_uint64 v = (signed char)pData[0];
          419  +        pData++;
          420  +        switch( eType ){
          421  +          case 7:
          422  +          case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
          423  +          case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
          424  +          case 4:  v = (v<<8) + pData[0];  pData++;
          425  +          case 3:  v = (v<<8) + pData[0];  pData++;
          426  +          case 2:  v = (v<<8) + pData[0];  pData++;
          427  +        }
          428  +  
          429  +        if( eType==7 ){
          430  +          double r;
          431  +          memcpy(&r, &v, sizeof(r));
          432  +          sqlite3_result_double(pCtx, r);
          433  +        }else{
          434  +          sqlite3_result_int64(pCtx, (sqlite3_int64)v);
          435  +        }
          436  +        break;
   418    437         }
   419         -
   420         -      if( eType==7 ){
   421         -        double r;
   422         -        memcpy(&r, &v, sizeof(r));
   423         -        sqlite3_result_double(pCtx, r);
   424         -      }else{
   425         -        sqlite3_result_int64(pCtx, (sqlite3_int64)v);
   426         -      }
   427         -      break;
   428         -    }
   429         -
   430         -    default: {
   431         -      int n = ((eType-12) / 2);
   432         -      if( eType % 2 ){
   433         -        sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
   434         -      }else{
   435         -        sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
          438  +  
          439  +      default: {
          440  +        int n = ((eType-12) / 2);
          441  +        if( eType % 2 ){
          442  +          sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
          443  +        }else{
          444  +          sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
          445  +        }
   436    446         }
   437    447       }
   438    448     }
   439    449   }
   440         -
   441    450   
   442    451   /*
   443    452   ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
   444    453   */
   445    454   static int dbdataNext(sqlite3_vtab_cursor *pCursor){
   446    455     DbdataCursor *pCsr = (DbdataCursor*)pCursor;
   447    456     DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
................................................................................
   724    733           break;
   725    734         case DBDATA_COLUMN_VALUE: {
   726    735           if( pCsr->iField<0 ){
   727    736             sqlite3_result_int64(ctx, pCsr->iIntkey);
   728    737           }else{
   729    738             sqlite3_int64 iType;
   730    739             dbdataGetVarint(pCsr->pHdrPtr, &iType);
   731         -          dbdataValue(ctx, iType, pCsr->pPtr);
          740  +          dbdataValue(
          741  +              ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
          742  +          );
   732    743           }
   733    744           break;
   734    745         }
   735    746       }
   736    747     }
   737    748     return SQLITE_OK;
   738    749   }