Author: hdu
Date: Fri Mar 16 10:52:55 2012
New Revision: 1301428

URL: http://svn.apache.org/viewvc?rev=1301428&view=rev
Log:
#i119048# handle edge cases when importing BDB hash files

Modified:
    incubator/ooo/trunk/main/desktop/source/deployment/dp_persmap.cxx

Modified: incubator/ooo/trunk/main/desktop/source/deployment/dp_persmap.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/desktop/source/deployment/dp_persmap.cxx?rev=1301428&r1=1301427&r2=1301428&view=diff
==============================================================================
--- incubator/ooo/trunk/main/desktop/source/deployment/dp_persmap.cxx (original)
+++ incubator/ooo/trunk/main/desktop/source/deployment/dp_persmap.cxx Fri Mar 
16 10:52:55 2012
@@ -372,45 +372,62 @@ bool PersistentMap::importFromBDB()
                nOfs += nBytesRead;
        }
 
-       // check BDB file header for non_encrypted Hash_v9 format
-       if( nFileSize < 0x1000)
+       // check BDB file header for non_encrypted Hash format v4..9
+       if( nFileSize < 0x0100)
                return false;
-       if( (aRawBDB[12]!=0x61 || aRawBDB[13]!=0x15 || aRawBDB[14]!=0x06)
-       &&  (aRawBDB[15]!=0x61 || aRawBDB[14]!=0x15 || aRawBDB[13]!=0x06))
+       if( aRawBDB[24] != 0) // only not-encrypted migration
                return false;
-       if( aRawBDB[16]!=0x09)
+       if( aRawBDB[25] != 8) // we expect a P_HASHMETA page
                return false;
-       
-       // find PackageManagers new_style entries
-       // using a simple heuristic for BDB_Hash_v9 files
+       const bool bLE = (aRawBDB[12]==0x61 && aRawBDB[13]==0x15 && 
aRawBDB[14]==0x06);
+       const bool bBE = (aRawBDB[15]==0x61 && aRawBDB[14]==0x15 && 
aRawBDB[13]==0x06);
+       if( bBE == bLE)
+               return false;
+       if( (aRawBDB[16] < 4) || (9 < aRawBDB[16])) // version
+               return false;
+       const sal_uInt64 nPgSize = bLE
+       ?       (aRawBDB[20] + (aRawBDB[21]<<8) + (aRawBDB[22]<<16) + 
(aRawBDB[23]<<24))
+       :       (aRawBDB[23] + (aRawBDB[22]<<8) + (aRawBDB[21]<<16) + 
(aRawBDB[20]<<24));
+       const int nPgCount = nFileSize / nPgSize;
+       if( nPgCount * nPgSize != nFileSize)
+               return false;
+
+       // find PackageManager's new_style entries
+       // using a simple heuristic for BDB_Hash pages
        int nEntryCount = 0;
-       const sal_uInt8* pBeg = &aRawBDB[0] + 0x1000;
-       const sal_uInt8* pEnd = pBeg + nFileSize;
-       for( const sal_uInt8* pCur = pBeg; pCur < pEnd; ++pCur) {
-               if( pCur[0] != 0x01)
-                       continue;
-               // get the value-candidate
-               const sal_uInt8* pVal = pCur + 1;
-               while( ++pCur < pEnd)
-                       if( (*pCur < ' ') || ((*pCur > 0x7F) && (*pCur != 
0xFF)))
-                               break;
-               if( pCur >= pEnd)
-                       break;
-               if( (pCur[0] != 0x01) || (pCur[1] != 0xFF))
-                       continue;
-               const OString aVal( (sal_Char*)pVal, pCur - pVal);
-               // get the key-candidate
-               const sal_uInt8* pKey = pCur + 1;
-               while( ++pCur < pEnd)
-                       if( (*pCur < ' ') || ((*pCur > 0x7F) && (*pCur != 
0xFF)))
+       for( int nPgNo = 1; nPgNo < nPgCount; ++nPgNo) {
+               // parse the next _db_page
+               const sal_uInt8* const pPage = &aRawBDB[ nPgNo * nPgSize];
+               const sal_uInt8* const pEnd = pPage + nPgSize;
+               const int nHfOffset = bLE ? (pPage[22] + (pPage[23]<<8)) : 
(pPage[23] + (pPage[22]<<8)); 
+               const sal_uInt8* pCur = pPage + nHfOffset;
+               // iterate through the entries
+               for(; pCur < pEnd; ++pCur) {
+                       if( pCur[0] != 0x01)
+                               continue;
+                       // get the value-candidate
+                       const sal_uInt8* pVal = pCur + 1;
+                       while( ++pCur < pEnd)
+                               if( (*pCur < ' ') || ((*pCur > 0x7F) && (*pCur 
!= 0xFF)))
+                                       break;
+                       if( pCur >= pEnd)
                                break;
-               if( (pCur < pEnd) && (*pCur > 0x01))
-                       continue;
-               const OString aKey( (sal_Char*)pKey, pCur - pKey);
-               
-               // add the key/value pair
-               add( aKey, aVal);
-               ++nEntryCount;
+                       if( (pCur[0] != 0x01) || (pCur[1] != 0xFF))
+                               continue;
+                       const OString aVal( (sal_Char*)pVal, pCur - pVal);
+                       // get the key-candidate
+                       const sal_uInt8* pKey = pCur + 1;
+                       while( ++pCur < pEnd)
+                               if( (*pCur < ' ') || ((*pCur > 0x7F) && (*pCur 
!= 0xFF)))
+                                       break;
+                       if( (pCur < pEnd) && (*pCur > 0x01))
+                               continue;
+                       const OString aKey( (sal_Char*)pKey, pCur - pKey);
+                       
+                       // add the key/value pair
+                       add( aKey, aVal);
+                       ++nEntryCount;
+               }
        }
 
        return (nEntryCount > 0);


Reply via email to