aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2021-05-24 14:35:19 +0000
committerdan <Dan Kennedy>2021-05-24 14:35:19 +0000
commitc00727ab583ea47f6962aa33dfc84f2d3723dc04 (patch)
tree1fb6cc28d38e91a268e6b2585b4cfc05a6e3980c /src
parent0fcf6f01e7a81647ca34b540540e0905d6042899 (diff)
downloadsqlite-c00727ab583ea47f6962aa33dfc84f2d3723dc04.tar.gz
sqlite-c00727ab583ea47f6962aa33dfc84f2d3723dc04.zip
Fix a problem in the in-memory journal code that could occasionally lead to a segfault when a sub-transaction that modified zero pages was committed.
FossilOrigin-Name: 17960165f5840cab45b7a8bb02779ebfb321c68f33ec6da9ab14063ccd134fa4
Diffstat (limited to 'src')
-rw-r--r--src/memjournal.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/src/memjournal.c b/src/memjournal.c
index 660a84267..598d5cc02 100644
--- a/src/memjournal.c
+++ b/src/memjournal.c
@@ -257,26 +257,28 @@ static int memjrnlWrite(
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
MemJournal *p = (MemJournal *)pJfd;
- FileChunk *pIter = 0;
-
- if( size==0 ){
- memjrnlFreeChunks(p->pFirst);
- p->pFirst = 0;
- }else{
- i64 iOff = p->nChunkSize;
- for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
- iOff += p->nChunkSize;
- }
- if( ALWAYS(pIter) ){
- memjrnlFreeChunks(pIter->pNext);
- pIter->pNext = 0;
+ assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 );
+ if( size<p->endpoint.iOffset ){
+ FileChunk *pIter = 0;
+ if( size==0 ){
+ memjrnlFreeChunks(p->pFirst);
+ p->pFirst = 0;
+ }else{
+ i64 iOff = p->nChunkSize;
+ for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
+ iOff += p->nChunkSize;
+ }
+ if( ALWAYS(pIter) ){
+ memjrnlFreeChunks(pIter->pNext);
+ pIter->pNext = 0;
+ }
}
- }
- p->endpoint.pChunk = pIter;
- p->endpoint.iOffset = size;
- p->readpoint.pChunk = 0;
- p->readpoint.iOffset = 0;
+ p->endpoint.pChunk = pIter;
+ p->endpoint.iOffset = size;
+ p->readpoint.pChunk = 0;
+ p->readpoint.iOffset = 0;
+ }
return SQLITE_OK;
}