@@ -694,11 +694,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
694694** Clear the Rtree.pNodeBlob object
695695*/
696696static void nodeBlobReset (Rtree * pRtree ){
697- if ( pRtree -> pNodeBlob && pRtree -> inWrTrans == 0 && pRtree -> nCursor == 0 ){
698- sqlite3_blob * pBlob = pRtree -> pNodeBlob ;
699- pRtree -> pNodeBlob = 0 ;
700- sqlite3_blob_close (pBlob );
701- }
697+ sqlite3_blob * pBlob = pRtree -> pNodeBlob ;
698+ pRtree -> pNodeBlob = 0 ;
699+ sqlite3_blob_close (pBlob );
702700}
703701
704702/*
@@ -742,7 +740,6 @@ static int nodeAcquire(
742740 & pRtree -> pNodeBlob );
743741 }
744742 if ( rc ){
745- nodeBlobReset (pRtree );
746743 * ppNode = 0 ;
747744 /* If unable to open an sqlite3_blob on the desired row, that can only
748745 ** be because the shadow tables hold erroneous data. */
@@ -802,6 +799,7 @@ static int nodeAcquire(
802799 }
803800 * ppNode = pNode ;
804801 }else {
802+ nodeBlobReset (pRtree );
805803 if ( pNode ){
806804 pRtree -> nNodeRef -- ;
807805 sqlite3_free (pNode );
@@ -946,6 +944,7 @@ static void nodeGetCoord(
946944 int iCoord , /* Which coordinate to extract */
947945 RtreeCoord * pCoord /* OUT: Space to write result to */
948946){
947+ assert ( iCell < NCELL (pNode ) );
949948 readCoord (& pNode -> zData [12 + pRtree -> nBytesPerCell * iCell + 4 * iCoord ], pCoord );
950949}
951950
@@ -1135,7 +1134,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
11351134 sqlite3_finalize (pCsr -> pReadAux );
11361135 sqlite3_free (pCsr );
11371136 pRtree -> nCursor -- ;
1138- nodeBlobReset (pRtree );
1137+ if ( pRtree -> nCursor == 0 && pRtree -> inWrTrans == 0 ){
1138+ nodeBlobReset (pRtree );
1139+ }
11391140 return SQLITE_OK ;
11401141}
11411142
@@ -1720,7 +1721,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
17201721 int rc = SQLITE_OK ;
17211722 RtreeNode * pNode = rtreeNodeOfFirstSearchPoint (pCsr , & rc );
17221723 if ( rc == SQLITE_OK && ALWAYS (p ) ){
1723- * pRowid = nodeGetRowid (RTREE_OF_CURSOR (pCsr ), pNode , p -> iCell );
1724+ if ( p -> iCell >=NCELL (pNode ) ){
1725+ rc = SQLITE_ABORT ;
1726+ }else {
1727+ * pRowid = nodeGetRowid (RTREE_OF_CURSOR (pCsr ), pNode , p -> iCell );
1728+ }
17241729 }
17251730 return rc ;
17261731}
@@ -1738,6 +1743,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
17381743
17391744 if ( rc ) return rc ;
17401745 if ( NEVER (p == 0 ) ) return SQLITE_OK ;
1746+ if ( p -> iCell >=NCELL (pNode ) ) return SQLITE_ABORT ;
17411747 if ( i == 0 ){
17421748 sqlite3_result_int64 (ctx , nodeGetRowid (pRtree , pNode , p -> iCell ));
17431749 }else if ( i <=pRtree -> nDim2 ){
@@ -3219,8 +3225,7 @@ static int rtreeUpdate(
32193225*/
32203226static int rtreeBeginTransaction (sqlite3_vtab * pVtab ){
32213227 Rtree * pRtree = (Rtree * )pVtab ;
3222- assert ( pRtree -> inWrTrans == 0 );
3223- pRtree -> inWrTrans ++ ;
3228+ pRtree -> inWrTrans = 1 ;
32243229 return SQLITE_OK ;
32253230}
32263231
@@ -3234,6 +3239,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){
32343239 nodeBlobReset (pRtree );
32353240 return SQLITE_OK ;
32363241}
3242+ static int rtreeRollback (sqlite3_vtab * pVtab ){
3243+ return rtreeEndTransaction (pVtab );
3244+ }
32373245
32383246/*
32393247** The xRename method for rtree module virtual tables.
@@ -3352,7 +3360,7 @@ static sqlite3_module rtreeModule = {
33523360 rtreeBeginTransaction , /* xBegin - begin transaction */
33533361 rtreeEndTransaction , /* xSync - sync transaction */
33543362 rtreeEndTransaction , /* xCommit - commit transaction */
3355- rtreeEndTransaction , /* xRollback - rollback transaction */
3363+ rtreeRollback , /* xRollback - rollback transaction */
33563364 0 , /* xFindFunction - function overloading */
33573365 rtreeRename , /* xRename - rename the table */
33583366 rtreeSavepoint , /* xSavepoint */
0 commit comments