Checkin f5ee3042 introduces a memory leak in zipfile.c. It is still
present on trunk, tested with 0b1dbd60.
Cause: zipfileDeflate() calls deflateInit2() twice and allocates zlib
stream memory twice in certain situations.
Also, deflateEnd(&str); may not be called if aOut is not allocated after
an out of memory situation.
A test case to reproduce the memory leak follows below.
Possible fix:
static int zipfileDeflate(
const u8 *aIn, int nIn, /* Input */
u8 **ppOut, int *pnOut, /* Output */
char **pzErr /* OUT: Error message */
){
int rc = SQLITE_OK;
sqlite3_int64 nAlloc;
z_stream str;
u8 *aOut;
memset(&str, 0, sizeof(str));
str.next_in = (Bytef*)aIn;
str.avail_in = nIn;
deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
nAlloc = deflateBound(&str, nIn);
aOut = (u8*)sqlite3_malloc64(nAlloc);
if( aOut==0 ){
rc = SQLITE_NOMEM;
}else{
int res;
str.next_out = aOut;
str.avail_out = nAlloc;
/* Remove: deflateInit2(&str, 9, Z_DEFLATED, -15, 8,
Z_DEFAULT_STRATEGY); */
res = deflate(&str, Z_FINISH);
if( res==Z_STREAM_END ){
*ppOut = aOut;
*pnOut = (int)str.total_out;
}else{
sqlite3_free(aOut);
*pzErr = sqlite3_mprintf("zipfile: deflate() error");
rc = SQLITE_ERROR;
}
/* Move below: deflateEnd(&str); */
}
deflateEnd(&str); /* Move from above. */
return rc;
}
Ralf
----------------------------------------------
#include <stdio.h>
#include "sqlite3.h"
static void check(int r, int e) {
if (r != e) {
printf ("ERROR %d, expected %d\n", e, r);
}
}
static int callback (void *user, int nCol, char **r, char **c) {
int i;
for (i = 0; i < nCol; i++) {
printf("%s ", r[i]);
}
printf("\n");
return 0;
}
extern int sqlite3_zipfile_init(sqlite3*,char**,const
sqlite3_api_routines*);
int main(void)
{
sqlite3 *db, *dbRbu;
int rc;
remove ("test.db");
remove ("test.zip");
check(SQLITE_OK, sqlite3_open_v2 ("test.db", &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL));
check(SQLITE_OK, sqlite3_zipfile_init(db, NULL, NULL));
check(SQLITE_OK, sqlite3_exec(db,
"CREATE VIRTUAL TABLE temp.zz USING zipfile('test.zip');",
callback, NULL, NULL));
check(SQLITE_OK, sqlite3_exec(db,
"INSERT INTO zz(name, mode, mtime, data) VALUES('h.txt'," \
" '-rw-r--r--', 1000000004, 'aaaaaaaaaabbbbbbbbbb'" \
");",
callback, NULL, NULL));
sqlite3_close(db);
printf("Done - Press ENTER to exit.\n");
getchar();
return 0;
}
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users