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 sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users