fix: deep copy ovfl cells to avoid double free
This commit is contained in:
parent
2f5b1a0030
commit
66bcf1fad6
|
@ -489,7 +489,7 @@ static int tdbBtreeBalanceDeeper(SBTree *pBt, SPage *pRoot, SPage **ppChild, TXN
|
|||
}
|
||||
|
||||
// Copy the root page content to the child page
|
||||
tdbPageCopy(pRoot, pChild);
|
||||
tdbPageCopy(pRoot, pChild, 0);
|
||||
|
||||
// Reinitialize the root page
|
||||
zArg.flags = TDB_BTREE_ROOT;
|
||||
|
@ -742,7 +742,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
for (int i = 0; i < nOlds; i++) {
|
||||
tdbPageCreate(pOlds[0]->pageSize, &pOldsCopy[i], tdbDefaultMalloc, NULL);
|
||||
tdbBtreeInitPage(pOldsCopy[i], &iarg, 0);
|
||||
tdbPageCopy(pOlds[i], pOldsCopy[i]);
|
||||
tdbPageCopy(pOlds[i], pOldsCopy[i], 0);
|
||||
}
|
||||
iNew = 0;
|
||||
nNewCells = 0;
|
||||
|
@ -840,7 +840,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
i8 flags = TDB_BTREE_ROOT | TDB_BTREE_PAGE_IS_LEAF(pNews[0]);
|
||||
// copy content to the parent page
|
||||
tdbBtreeInitPage(pParent, &(SBtreeInitPageArg){.flags = flags, .pBt = pBt}, 0);
|
||||
tdbPageCopy(pNews[0], pParent);
|
||||
tdbPageCopy(pNews[0], pParent, 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
|
|
@ -229,7 +229,7 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tdbPageCopy(SPage *pFromPage, SPage *pToPage) {
|
||||
void tdbPageCopy(SPage *pFromPage, SPage *pToPage, int deepCopyOvfl) {
|
||||
int delta, nFree;
|
||||
|
||||
pToPage->pFreeStart = pToPage->pPageHdr + (pFromPage->pFreeStart - pFromPage->pPageHdr);
|
||||
|
@ -250,8 +250,15 @@ void tdbPageCopy(SPage *pFromPage, SPage *pToPage) {
|
|||
|
||||
// Copy the overflow cells
|
||||
for (int iOvfl = 0; iOvfl < pFromPage->nOverflow; iOvfl++) {
|
||||
SCell *pNewCell = pFromPage->apOvfl[iOvfl];
|
||||
if (deepCopyOvfl) {
|
||||
int szCell = (*pFromPage->xCellSize)(pFromPage, pFromPage->apOvfl[iOvfl], 0, NULL, NULL);
|
||||
pNewCell = (SCell *)tdbOsMalloc(szCell);
|
||||
memcpy(pNewCell, pFromPage->apOvfl[iOvfl], szCell);
|
||||
}
|
||||
|
||||
pToPage->apOvfl[iOvfl] = pNewCell;
|
||||
pToPage->aiOvfl[iOvfl] = pFromPage->aiOvfl[iOvfl];
|
||||
pToPage->apOvfl[iOvfl] = pFromPage->apOvfl[iOvfl];
|
||||
}
|
||||
pToPage->nOverflow = pFromPage->nOverflow;
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell
|
|||
int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl);
|
||||
int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt);
|
||||
int tdbPageUpdateCell(SPage *pPage, int idx, SCell *pCell, int szCell, TXN *pTxn, SBTree *pBt);
|
||||
void tdbPageCopy(SPage *pFromPage, SPage *pToPage);
|
||||
void tdbPageCopy(SPage *pFromPage, SPage *pToPage, int copyOvflCells);
|
||||
int tdbPageCapacity(int pageSize, int amHdrSize);
|
||||
|
||||
static inline SCell *tdbPageGetCell(SPage *pPage, int idx) {
|
||||
|
|
Loading…
Reference in New Issue