@@ -40,16 +40,20 @@ SOFTWARE.
40
40
#include <CommonCrypto/CommonDigest.h>
41
41
#include <CommonCrypto/CommonCryptor.h>
42
42
43
- // Size of standard Sqlite3 pager header
44
- #define CEVFS_DB_HEADER1_SZ 100
45
- // Size of cevfs-specific pager header
46
- #define CEVFS_DB_HEADER2_SZ 100
43
+ // Standard Sqlite3 pager header
47
44
#define CEVFS_DB_HEADER1_OFST 000
45
+ #define CEVFS_DB_HEADER1_SZ 100
46
+
47
+ // cevfs-specific pager header
48
48
#define CEVFS_DB_HEADER2_OFST CEVFS_DB_HEADER1_OFST+CEVFS_DB_HEADER1_SZ
49
- // Offset to master map table
50
- #define CEVFS_DB_MMTBL_OFST CEVFS_DB_HEADER2_OFST+CEVFS_DB_HEADER2_SZ
49
+ #define CEVFS_DB_HEADER2_SZ 100
50
+
51
+ // Total header size
51
52
#define CEVFS_DB_HEADER_SIZE (CEVFS_DB_HEADER1_SZ + CEVFS_DB_HEADER2_SZ)
52
53
54
+ // Offset to master map table, starts just after header
55
+ #define CEVFS_DB_MMTBL_OFST CEVFS_DB_HEADER2_OFST+CEVFS_DB_HEADER2_SZ
56
+
53
57
#define CEVFS_FILE_SCHEMA_NO 1
54
58
#define CEVFS_FIRST_MAPPED_PAGE 3
55
59
@@ -266,7 +270,6 @@ static char * cevfsMapPath(cevfs_file *pFile, const char *zName, bool *bMustRele
266
270
static const char * zTail = "btree" ;
267
271
if (bMustRelease ) * bMustRelease = false;
268
272
if ( strstr (zName , "-journal" )== 0 ){
269
- bMustRelease = false;
270
273
return (char * )zName ;
271
274
}
272
275
char * zUppJournalPath = pFile ? pFile -> zUppJournalPath : NULL ;
@@ -614,7 +617,7 @@ static int cevfsLoadHeader(cevfs_file *p){
614
617
615
618
static CevfsMemPage * memPageFromDbPage (DbPage * pDbPage , Pgno mappedPgno ){
616
619
CevfsMemPage * pPg = (CevfsMemPage * )sqlite3PagerGetExtra (pDbPage );
617
- if (mappedPgno != pPg -> pgno ){
620
+ if ( mappedPgno != pPg -> pgno ){
618
621
pPg -> pgno = mappedPgno ;
619
622
pPg -> pDbPage = pDbPage ;
620
623
pPg -> dbHdrOffset = mappedPgno == 1 ? CEVFS_DB_HEADER_SIZE : 0 ;
@@ -749,7 +752,7 @@ void cevfsAllocCmpPageSpace(
749
752
//u32 realPageSize = pFile->pageSize - (header->currPgno == 1 ? CEVFS_DB_HEADER_SIZE : 0);
750
753
header -> currPageOfst += cmpSz ;
751
754
if ( header -> currPageOfst > /*realPageSize*/ pFile -> pageSize ){
752
- // current page can't hold anymore , start new page.
755
+ // current page can't hold any more , start new page.
753
756
ofst = 0 ;
754
757
header -> currPageOfst = cmpSz ;
755
758
// Make sure to not use a pgno that we allocated to a pagemap page.
@@ -841,7 +844,7 @@ static int cevfsPageMapSet(
841
844
842
845
if ( (rc = cevfsPageMapGet (pFile , uppOfst , outUppPgno , outLwrPgno , outCmpOfst , & oldCmpSz , & ix ))== SQLITE_OK ){
843
846
/*
844
- ** We found a map entry. It's either a placeholder entry that need valid data,
847
+ ** We found a map entry. It's either a placeholder entry that needs valid data,
845
848
** an outdated entry that needs updating, or a valid up-to-date entry.
846
849
** If the entry needs updating, we will reuse the space used to hold the previously compressed
847
850
** data if the compressed data now takes up less space or allocate a new space at the end of
@@ -960,29 +963,40 @@ static int cevfsRead(
960
963
Pgno uppPgno , mappedPgno ;
961
964
CevfsCmpOfst cmprPgOfst ;
962
965
CevfsCmpSize uCmpPgSz ;
966
+
963
967
if ( (rc = cevfsPageMapGet (p , iOfst , & uppPgno , & mappedPgno , & cmprPgOfst , & uCmpPgSz , NULL )) == SQLITE_OK ){
964
- if ( rc == SQLITE_OK && (rc = sqlite3PagerGet (p -> pPager , mappedPgno , & pPage , 0 )) == SQLITE_OK ){
968
+ if ( rc == SQLITE_OK &&
969
+ (rc = sqlite3PagerGet (p -> pPager , mappedPgno , & pPage , 0 ))== SQLITE_OK
970
+ ){
971
+ void * pDecBuf = NULL ;
972
+ void * pUncBuf = NULL ;
973
+ void * pDstData = NULL ;
974
+
965
975
CevfsMemPage * pMemPage = memPageFromDbPage (pPage , mappedPgno );
966
976
CEVFS_PRINTF (
967
977
pInfo , "%s.xRead(%s,pgno=%u->%u,ofst=%08lld->%u,amt=%d->%u)" ,
968
978
pInfo -> zVfsName , p -> zFName , uppPgno , mappedPgno , iOfst , cmprPgOfst , iAmt , uCmpPgSz
969
979
);
970
980
assert ( uCmpPgSz > 0 );
981
+
971
982
size_t iDstAmt = uppPgSz ;
972
- void * pUncBuf = sqlite3_malloc ((int )iDstAmt );
973
- void * pCmpBuf = sqlite3_malloc (uCmpPgSz );
974
- int bSuccess = 0 ;
975
-
976
- if ( pUncBuf ){
977
- // If using encryption, the IV is stored first followed by the enctypted data
978
- void * iv =
979
- (char * )pMemPage -> aData
980
- + pMemPage -> dbHdrOffset
981
- + pMemPage -> pgHdrOffset
982
- + cmprPgOfst ;
983
-
984
- // decrypt
985
- if ( p -> bEncryptionEnabled ){
983
+ int bSuccess = 1 ;
984
+
985
+ void * pSrcData =
986
+ (char * )pMemPage -> aData
987
+ + pMemPage -> dbHdrOffset
988
+ + pMemPage -> pgHdrOffset
989
+ + cmprPgOfst ;
990
+
991
+ // src = dst, assuming no encryption or compression
992
+ pDstData = pSrcData ;
993
+
994
+ if ( p -> bEncryptionEnabled ){
995
+ // The IV is stored first followed by the enctypted data
996
+ void * iv = pSrcData ;
997
+
998
+ pDecBuf = sqlite3_malloc (uCmpPgSz );
999
+ if ( pDecBuf ){
986
1000
void * srcData = iv + p -> nEncIvSz ;
987
1001
size_t nDataInSize = uCmpPgSz - p -> nEncIvSz ;
988
1002
size_t nFinalSz ;
@@ -992,38 +1006,36 @@ static int cevfsRead(
992
1006
srcData , // dataIn
993
1007
nDataInSize , // data-in length
994
1008
iv , // IvIn
995
- pCmpBuf , // dataOut; result is written here.
1009
+ pDecBuf , // dataOut; result is written here.
996
1010
uCmpPgSz , // The size of the dataOut buffer in bytes
997
1011
& nFinalSz // On successful return, the number of bytes written to dataOut.
998
1012
);
999
1013
1000
1014
if ( bSuccess ){
1001
1015
uCmpPgSz = nFinalSz ;
1002
- }
1003
- }else {
1004
- bSuccess = true;
1005
- pCmpBuf = iv ;
1006
- }
1007
-
1008
- // uncompress
1009
- if ( bSuccess ){
1010
- if ( p -> bCompressionEnabled ){
1011
- bSuccess = p -> vfsMethods .xUncompress (pInfo -> pCtx , pUncBuf , & iDstAmt , pCmpBuf , (int )uCmpPgSz );
1012
- if ( !bSuccess ){
1013
- return CEVFS_ERROR_DECOMPRESSION_FAILED ;
1014
- }
1016
+ pSrcData = pDstData = pDecBuf ;
1017
+ }else rc = CEVFS_ERROR_DECRYPTION_FAILED ;
1018
+ }else rc = SQLITE_NOMEM ;
1019
+ } // encryption
1020
+
1021
+ if ( p -> bCompressionEnabled && bSuccess && bSuccess && rc == SQLITE_OK ){
1022
+ pUncBuf = sqlite3_malloc ((int )iDstAmt );
1023
+ if ( pUncBuf ){
1024
+ bSuccess = p -> vfsMethods .xUncompress (pInfo -> pCtx , pUncBuf , & iDstAmt , pSrcData , (int )uCmpPgSz );
1025
+ if ( bSuccess ){
1015
1026
assert ( iDstAmt == uppPgSz );
1016
- }else {
1017
- pUncBuf = pCmpBuf ;
1018
- }
1019
- sqlite3_free (pCmpBuf );
1020
- u16 uBufOfst = iOfst % uppPgSz ;
1021
- memcpy (zBuf , pUncBuf + uBufOfst , iAmt );
1022
- }else {
1023
- rc = CEVFS_ERROR_DECRYPTION_FAILED ;
1024
- }
1025
- sqlite3_free (pUncBuf );
1026
- }else rc = SQLITE_NOMEM ;
1027
+ pDstData = pUncBuf ;
1028
+ }else rc = CEVFS_ERROR_DECOMPRESSION_FAILED ;
1029
+ }else rc = SQLITE_NOMEM ;
1030
+ }
1031
+
1032
+ if ( bSuccess && rc == SQLITE_OK ){
1033
+ u16 uBufOfst = iOfst % uppPgSz ;
1034
+ memcpy (zBuf , pDstData + uBufOfst , iAmt );
1035
+ }
1036
+
1037
+ if ( pDecBuf ) sqlite3_free ( pDecBuf );
1038
+ if ( pUncBuf ) sqlite3_free ( pUncBuf );
1027
1039
sqlite3PagerUnref (pPage );
1028
1040
}
1029
1041
}else {
@@ -1050,65 +1062,84 @@ static int cevfsWrite(
1050
1062
){
1051
1063
cevfs_file * p = (cevfs_file * )pFile ;
1052
1064
cevfs_info * pInfo = p -> pInfo ;
1053
- int rc ;
1065
+ int rc = SQLITE_OK ;
1054
1066
1055
1067
if ( p -> pPager ){
1056
- DbPage * pPage ;
1057
- Pgno uppPgno , mappedPgno ;
1068
+ if ( p -> bReadOnly ) rc = SQLITE_READONLY ;
1069
+ else {
1070
+ void * pCmpBuf = NULL ;
1071
+ void * pEncBuf = NULL ;
1072
+ void * pSrcData = (void * )zBuf ;
1073
+ size_t nSrcAmt = iAmt ;
1074
+ int bSuccess = 1 ;
1075
+
1076
+ if ( p -> bCompressionEnabled ){
1077
+ size_t nDest = p -> vfsMethods .xCompressBound (pInfo -> pCtx , nSrcAmt );
1078
+ pCmpBuf = sqlite3_malloc ((int )nDest );
1079
+ if ( pCmpBuf ){
1080
+ bSuccess = p -> vfsMethods .xCompress (pInfo -> pCtx , pCmpBuf , & nDest , pSrcData , nSrcAmt );
1081
+ if ( bSuccess ){
1082
+ pSrcData = pCmpBuf ;
1083
+ nSrcAmt = nDest ;
1084
+ }
1085
+ }else rc = SQLITE_NOMEM ;
1086
+ }
1058
1087
1059
- if ( !p -> bReadOnly ){
1060
- // compress
1061
- size_t nDest = p -> vfsMethods .xCompressBound (pInfo -> pCtx , iAmt );
1062
- void * pCmpBuf = sqlite3_malloc ((int )nDest );
1063
- if ( pCmpBuf ){
1064
- CevfsCmpOfst cmprPgOfst ;
1065
- p -> vfsMethods .xCompress (pInfo -> pCtx , pCmpBuf , & nDest , (void * )zBuf , iAmt );
1066
-
1067
- // encrypt
1068
- void * pEncBuf = NULL ;
1088
+ if ( p -> bEncryptionEnabled && bSuccess ){
1069
1089
size_t tmp_csz = 0 ;
1070
- int bSuccess = 0 ;
1071
-
1072
1090
void * iv = sqlite3_malloc ((int )p -> nEncIvSz );
1073
- if ( p -> bEncryptionEnabled ){
1091
+ if ( iv ){
1074
1092
bSuccess = p -> vfsMethods .xEncrypt (
1075
1093
pInfo -> pCtx ,
1076
- pCmpBuf , // dataIn
1077
- nDest , // data-in length
1094
+ pSrcData , // dataIn
1095
+ nSrcAmt , // data-in length
1078
1096
iv , // IV out
1079
1097
& pEncBuf , // dataOut; result is written here.
1080
1098
& tmp_csz , // On successful return, the number of bytes written to dataOut.
1081
1099
sqlite3_malloc
1082
1100
);
1083
- }
1101
+ if ( bSuccess && pEncBuf ){
1102
+ // Join IV and pEncBuf. If IV is greater than pInfo->nEncIvSz, it will be truncated.
1103
+ void * pIvEncBuf = NULL ;
1104
+ CevfsCmpSize uIvEncSz = p -> nEncIvSz + tmp_csz ;
1105
+ pIvEncBuf = sqlite3_realloc (iv , (int )(uIvEncSz ));
1106
+ memcpy (pIvEncBuf + p -> nEncIvSz , pEncBuf , tmp_csz );
1107
+ sqlite3_free (pEncBuf );
1108
+ pSrcData = pEncBuf = pIvEncBuf ;
1109
+ nSrcAmt = uIvEncSz ;
1110
+ }else rc = CEVFS_ERROR_ENCRYPTION_FAILED ;
1111
+ }else rc = SQLITE_NOMEM ;
1112
+ }
1084
1113
1085
- if ( bSuccess && pEncBuf ){
1086
- // Join IV and pEncBuf. If IV is greater than pInfo->nEncIvSz, it will be truncated.
1087
- void * pIvEncBuf = sqlite3_realloc (iv , (int )(p -> nEncIvSz + tmp_csz ));
1088
- memcpy (pIvEncBuf + p -> nEncIvSz , pEncBuf , tmp_csz );
1114
+ // Make sure dest/lwr page size is large enough for incoming page of data
1115
+ assert ( nSrcAmt <= p -> pageSize );
1116
+ if ( rc == SQLITE_OK ){
1117
+ if ( nSrcAmt <= p -> pageSize ){
1118
+ DbPage * pPage ;
1119
+ Pgno uppPgno , mappedPgno ;
1120
+ CevfsCmpOfst cmprPgOfst ;
1089
1121
1090
- CevfsCmpSize uIvEncSz = tmp_csz + p -> nEncIvSz ;
1091
- cevfsPageMapSet (p , iOfst , uIvEncSz , & uppPgno , & mappedPgno , & cmprPgOfst );
1122
+ cevfsPageMapSet (p , iOfst , nSrcAmt , & uppPgno , & mappedPgno , & cmprPgOfst );
1092
1123
1093
1124
// write
1094
1125
if ( (rc = sqlite3PagerGet (p -> pPager , mappedPgno , & pPage , 0 ))== SQLITE_OK ){
1095
1126
CevfsMemPage * pMemPage = memPageFromDbPage (pPage , mappedPgno );
1096
- if ( (rc = cevfsPagerWrite (p , pPage ))== SQLITE_OK ){
1127
+ if ( rc == SQLITE_OK && (rc = cevfsPagerWrite (p , pPage ))== SQLITE_OK ){
1097
1128
CEVFS_PRINTF (
1098
1129
pInfo ,
1099
1130
"%s.xWrite(%s, pgno=%u->%u, offset=%08lld->%06lu, amt=%06d->%06d)" ,
1100
1131
pInfo -> zVfsName , p -> zFName ,
1101
1132
uppPgno , mappedPgno ,
1102
1133
iOfst , (unsigned long )(pMemPage -> dbHdrOffset + pMemPage -> pgHdrOffset + cmprPgOfst ),
1103
- iAmt , uIvEncSz
1134
+ iAmt , nSrcAmt
1104
1135
);
1105
1136
memcpy (
1106
1137
pMemPage -> aData
1107
1138
+ pMemPage -> dbHdrOffset
1108
1139
+ pMemPage -> pgHdrOffset
1109
1140
+ cmprPgOfst ,
1110
- pIvEncBuf ,
1111
- uIvEncSz
1141
+ pSrcData ,
1142
+ nSrcAmt
1112
1143
);
1113
1144
1114
1145
// Keep track of sizes of upper and lower pagers
@@ -1117,13 +1148,12 @@ static int cevfsWrite(
1117
1148
}
1118
1149
sqlite3PagerUnref (pPage );
1119
1150
}
1120
- sqlite3_free (pIvEncBuf );
1121
- }else {
1122
- rc = CEVFS_ERROR_ENCRYPTION_FAILED ;
1123
- }
1124
- sqlite3_free (pCmpBuf );
1125
- }else rc = SQLITE_NOMEM ;
1126
- }else rc = SQLITE_READONLY ;
1151
+ }else rc = CEVFS_ERROR_PAGE_SIZE_TOO_SMALL ;
1152
+ }
1153
+
1154
+ if ( pEncBuf ) sqlite3_free ( pEncBuf );
1155
+ if ( pCmpBuf ) sqlite3_free ( pCmpBuf );
1156
+ }
1127
1157
}else {
1128
1158
CEVFS_PRINTF (pInfo , "%s.xWrite(%s, offset=%08lld, amt=%06d)" , pInfo -> zVfsName , p -> zFName , iOfst , iAmt );
1129
1159
rc = p -> pReal -> pMethods -> xWrite (p -> pReal , zBuf , iAmt , iOfst );
@@ -1837,15 +1867,16 @@ int cevfs_build(
1837
1867
1838
1868
DbPage * pPage1 = NULL ;
1839
1869
// import all pages
1840
- for (Pgno i = 0 ; i < pageCount ; i ++ ){
1870
+ for (Pgno pgno = 0 ; pgno < pageCount ; pgno ++ ){
1841
1871
// read source page
1842
1872
DbPage * pPage ;
1843
- rc = sqlite3PagerGet (pPager , i + 1 , & pPage , 0 );
1873
+ rc = sqlite3PagerGet (pPager , pgno + 1 , & pPage , /* flags */ 0 );
1844
1874
if ( rc == SQLITE_OK ){
1845
- // write destination page
1875
+ // read source page
1846
1876
void * pData = sqlite3PagerGetData (pPage );
1847
- rc = cevfsWrite ((sqlite3_file * )pInfo -> pFile , pData , pageSize , pageSize * i );
1848
- if (i == 0 ) {
1877
+ // write destination page
1878
+ rc = cevfsWrite ((sqlite3_file * )pInfo -> pFile , pData , pageSize , pageSize * pgno );
1879
+ if ( pgno == 0 ){
1849
1880
// To be deallocated later
1850
1881
pPage1 = pPage ;
1851
1882
}else {
0 commit comments