diff options
Diffstat (limited to 'ext/session/sqlite3session.c')
-rw-r--r-- | ext/session/sqlite3session.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 1f6c58b4d..c96363b60 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1974,13 +1974,29 @@ int sqlite3session_attach( ** If successful, return zero. Otherwise, if an OOM condition is encountered, ** set *pRc to SQLITE_NOMEM and return non-zero. */ -static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ - if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){ +static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ +#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) + i64 nReq = p->nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ u8 *aNew; i64 nNew = p->nAlloc ? p->nAlloc : 128; + do { nNew = nNew*2; - }while( (size_t)(nNew-p->nBuf)<nByte ); + }while( nNew<nReq ); + + /* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation + ** of sqlite3_realloc64(). Allocations greater than this size in bytes + ** always fail. It is used here to ensure that this routine can always + ** allocate up to this limit - instead of up to the largest power of + ** two smaller than the limit. */ + if( nNew>SESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNew<nReq ){ + *pRc = SQLITE_NOMEM; + return 1; + } + } aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew); if( 0==aNew ){ |