From 0c076a46f24c20608858ff31c51c0b0b2c7b76c4 Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 24 Jul 2024 01:08:08 +0400 Subject: [PATCH 1/6] set error to pParse and preserve internal invariant about possible error inside the condition --- libsql-sqlite3/src/build.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/libsql-sqlite3/src/build.c b/libsql-sqlite3/src/build.c index 80a90663ce..8f5bd9f4e4 100644 --- a/libsql-sqlite3/src/build.c +++ b/libsql-sqlite3/src/build.c @@ -5628,6 +5628,19 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ int nCol = pIdx->nColumn; int nKey = pIdx->nKeyCol; KeyInfo *pKey; + char* zIndexName = NULL, *zDbSName = NULL; + iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); + if( 0 <= iDb && iDb < pParse->db->nDb ){ + zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); + if( zDbSName == NULL ){ + goto out_nomem; + } + } + zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + if( zIndexName == NULL ){ + goto out_nomem; + } + if( pParse->nErr ) return 0; if( pIdx->uniqNotNull ){ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); @@ -5635,12 +5648,9 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ - iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); assert( sqlite3KeyInfoIsWriteable(pKey) ); - pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); - if( 0 <= iDb && iDb < pParse->db->nDb ){ - pKey->zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); - } + pKey->zIndexName = zIndexName; + pKey->zDbSName = zDbSName; for(i=0; iazColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : @@ -5666,6 +5676,14 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } } return pKey; +out_nomem: + if( zIndexName != NULL ){ + sqlite3DbFree(pParse->db, zIndexName); + } + if( zDbSName != NULL ){ + sqlite3DbFree(pParse->db, zDbSName); + } + return sqlite3OomFault(pParse->db); } #ifndef SQLITE_OMIT_CTE From 02d34e30deac7b06040b1c2cba06f71b921772c8 Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 24 Jul 2024 13:02:47 +0400 Subject: [PATCH 2/6] fix potential memory leak --- libsql-sqlite3/src/build.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libsql-sqlite3/src/build.c b/libsql-sqlite3/src/build.c index 8f5bd9f4e4..817fe5c918 100644 --- a/libsql-sqlite3/src/build.c +++ b/libsql-sqlite3/src/build.c @@ -5629,24 +5629,25 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ int nKey = pIdx->nKeyCol; KeyInfo *pKey; char* zIndexName = NULL, *zDbSName = NULL; - iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); - if( 0 <= iDb && iDb < pParse->db->nDb ){ - zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); - if( zDbSName == NULL ){ - goto out_nomem; - } - } - zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); - if( zIndexName == NULL ){ - goto out_nomem; - } - if( pParse->nErr ) return 0; if( pIdx->uniqNotNull ){ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); }else{ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } + if( pKey ){ + iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); + if( 0 <= iDb && iDb < pParse->db->nDb ){ + zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); + if( zDbSName == NULL ){ + goto out_nomem; + } + } + zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + if( zIndexName == NULL ){ + goto out_nomem; + } + } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); pKey->zIndexName = zIndexName; From 66a57449c473fec04a8a8490c895969f28fc363e Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 24 Jul 2024 13:03:34 +0400 Subject: [PATCH 3/6] slightly adjust code --- libsql-sqlite3/src/build.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsql-sqlite3/src/build.c b/libsql-sqlite3/src/build.c index 817fe5c918..e4ca084d24 100644 --- a/libsql-sqlite3/src/build.c +++ b/libsql-sqlite3/src/build.c @@ -5636,6 +5636,8 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ + assert( sqlite3KeyInfoIsWriteable(pKey) ); + iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); if( 0 <= iDb && iDb < pParse->db->nDb ){ zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); @@ -5647,9 +5649,7 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ if( zIndexName == NULL ){ goto out_nomem; } - } - if( pKey ){ - assert( sqlite3KeyInfoIsWriteable(pKey) ); + pKey->zIndexName = zIndexName; pKey->zDbSName = zDbSName; for(i=0; i Date: Wed, 24 Jul 2024 16:45:58 +0400 Subject: [PATCH 4/6] small fix --- libsql-sqlite3/src/build.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsql-sqlite3/src/build.c b/libsql-sqlite3/src/build.c index e4ca084d24..a04ed315bd 100644 --- a/libsql-sqlite3/src/build.c +++ b/libsql-sqlite3/src/build.c @@ -5684,6 +5684,9 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ if( zDbSName != NULL ){ sqlite3DbFree(pParse->db, zDbSName); } + if( pKey != NULL ){ + sqlite3KeyInfoUnref(pKey); + } return sqlite3OomFault(pParse->db); } From b5b3e8ab76d2991d23ff8f41497e7648213c5d3e Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 24 Jul 2024 16:47:39 +0400 Subject: [PATCH 5/6] avoid pKey leak and simplify code --- libsql-sqlite3/src/build.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/libsql-sqlite3/src/build.c b/libsql-sqlite3/src/build.c index a04ed315bd..afba9b58d7 100644 --- a/libsql-sqlite3/src/build.c +++ b/libsql-sqlite3/src/build.c @@ -5628,7 +5628,6 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ int nCol = pIdx->nColumn; int nKey = pIdx->nKeyCol; KeyInfo *pKey; - char* zIndexName = NULL, *zDbSName = NULL; if( pParse->nErr ) return 0; if( pIdx->uniqNotNull ){ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); @@ -5640,18 +5639,16 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); if( 0 <= iDb && iDb < pParse->db->nDb ){ - zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); - if( zDbSName == NULL ){ + pKey->zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); + if( pKey->zDbSName == NULL ){ goto out_nomem; } } - zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); - if( zIndexName == NULL ){ + pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + if( pKey->zIndexName == NULL ){ goto out_nomem; } - pKey->zIndexName = zIndexName; - pKey->zDbSName = zDbSName; for(i=0; iazColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : @@ -5678,12 +5675,6 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } return pKey; out_nomem: - if( zIndexName != NULL ){ - sqlite3DbFree(pParse->db, zIndexName); - } - if( zDbSName != NULL ){ - sqlite3DbFree(pParse->db, zDbSName); - } if( pKey != NULL ){ sqlite3KeyInfoUnref(pKey); } From b7a9dd773b9f6cd27f0121959ee78aaa51b0575d Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 24 Jul 2024 16:50:04 +0400 Subject: [PATCH 6/6] build bundles --- .../SQLite3MultipleCiphers/src/sqlite3.c | 17 +++++++++++++++-- libsql-ffi/bundled/src/sqlite3.c | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c index d5a72ca3c3..c840cb8032 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c @@ -127426,12 +127426,20 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ - iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); assert( sqlite3KeyInfoIsWriteable(pKey) ); - pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + + iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); if( 0 <= iDb && iDb < pParse->db->nDb ){ pKey->zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); + if( pKey->zDbSName == NULL ){ + goto out_nomem; + } } + pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + if( pKey->zIndexName == NULL ){ + goto out_nomem; + } + for(i=0; iazColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : @@ -127457,6 +127465,11 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } } return pKey; +out_nomem: + if( pKey != NULL ){ + sqlite3KeyInfoUnref(pKey); + } + return sqlite3OomFault(pParse->db); } #ifndef SQLITE_OMIT_CTE diff --git a/libsql-ffi/bundled/src/sqlite3.c b/libsql-ffi/bundled/src/sqlite3.c index d5a72ca3c3..c840cb8032 100644 --- a/libsql-ffi/bundled/src/sqlite3.c +++ b/libsql-ffi/bundled/src/sqlite3.c @@ -127426,12 +127426,20 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ - iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); assert( sqlite3KeyInfoIsWriteable(pKey) ); - pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + + iDb = sqlite3SchemaToIndex(pParse->db, pIdx->pSchema); if( 0 <= iDb && iDb < pParse->db->nDb ){ pKey->zDbSName = sqlite3DbStrDup(pParse->db, pParse->db->aDb[iDb].zDbSName); + if( pKey->zDbSName == NULL ){ + goto out_nomem; + } } + pKey->zIndexName = sqlite3DbStrDup(pParse->db, pIdx->zName); + if( pKey->zIndexName == NULL ){ + goto out_nomem; + } + for(i=0; iazColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : @@ -127457,6 +127465,11 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } } return pKey; +out_nomem: + if( pKey != NULL ){ + sqlite3KeyInfoUnref(pKey); + } + return sqlite3OomFault(pParse->db); } #ifndef SQLITE_OMIT_CTE