1 /*
2 ** 2022-08-27
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 **
13 */
14 
15 
16 #include "sqlite3recover.h"
17 #include <assert.h>
18 #include <string.h>
19 
20 #ifndef SQLITE_OMIT_VIRTUALTABLE
21 
22 /*
23 ** Declaration for public API function in file dbdata.c. This may be called
24 ** with NULL as the final two arguments to register the sqlite_dbptr and
25 ** sqlite_dbdata virtual tables with a database handle.
26 */
27 #ifdef _WIN32
28 __declspec(dllexport)
29 #endif
30 int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*);
31 
32 typedef unsigned int u32;
33 typedef unsigned char u8;
34 typedef sqlite3_int64 i64;
35 
36 typedef struct RecoverTable RecoverTable;
37 typedef struct RecoverColumn RecoverColumn;
38 
39 /*
40 ** When recovering rows of data that can be associated with table
41 ** definitions recovered from the sqlite_schema table, each table is
42 ** represented by an instance of the following object.
43 **
44 ** iRoot:
45 **   The root page in the original database. Not necessarily (and usually
46 **   not) the same in the recovered database.
47 **
48 ** zTab:
49 **   Name of the table.
50 **
51 ** nCol/aCol[]:
52 **   aCol[] is an array of nCol columns. In the order in which they appear
53 **   in the table.
54 **
55 ** bIntkey:
56 **   Set to true for intkey tables, false for WITHOUT ROWID.
57 **
58 ** iRowidBind:
59 **   Each column in the aCol[] array has associated with it the index of
60 **   the bind parameter its values will be bound to in the INSERT statement
61 **   used to construct the output database. If the table does has a rowid
62 **   but not an INTEGER PRIMARY KEY column, then iRowidBind contains the
63 **   index of the bind paramater to which the rowid value should be bound.
64 **   Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY
65 **   KEY column, then the rowid value should be bound to the index associated
66 **   with the column.
67 **
68 ** pNext:
69 **   All RecoverTable objects used by the recovery operation are allocated
70 **   and populated as part of creating the recovered database schema in
71 **   the output database, before any non-schema data are recovered. They
72 **   are then stored in a singly-linked list linked by this variable beginning
73 **   at sqlite3_recover.pTblList.
74 */
75 struct RecoverTable {
76   u32 iRoot;                      /* Root page in original database */
77   char *zTab;                     /* Name of table */
78   int nCol;                       /* Number of columns in table */
79   RecoverColumn *aCol;            /* Array of columns */
80   int bIntkey;                    /* True for intkey, false for without rowid */
81   int iRowidBind;                 /* If >0, bind rowid to INSERT here */
82   RecoverTable *pNext;
83 };
84 
85 /*
86 ** Each database column is represented by an instance of the following object
87 ** stored in the RecoverTable.aCol[] array of the associated table.
88 **
89 ** iField:
90 **   The index of the associated field within database records. Or -1 if
91 **   there is no associated field (e.g. for virtual generated columns).
92 **
93 ** iBind:
94 **   The bind index of the INSERT statement to bind this columns values
95 **   to. Or 0 if there is no such index (iff (iField<0)).
96 **
97 ** bIPK:
98 **   True if this is the INTEGER PRIMARY KEY column.
99 **
100 ** zCol:
101 **   Name of column.
102 **
103 ** eHidden:
104 **   A RECOVER_EHIDDEN_* constant value (see below for interpretation of each).
105 */
106 struct RecoverColumn {
107   int iField;                     /* Field in record on disk */
108   int iBind;                      /* Binding to use in INSERT */
109   int bIPK;                       /* True for IPK column */
110   char *zCol;
111   int eHidden;
112 };
113 
114 #define RECOVER_EHIDDEN_NONE    0      /* Normal database column */
115 #define RECOVER_EHIDDEN_HIDDEN  1      /* Column is __HIDDEN__ */
116 #define RECOVER_EHIDDEN_VIRTUAL 2      /* Virtual generated column */
117 #define RECOVER_EHIDDEN_STORED  3      /* Stored generated column */
118 
119 /*
120 ** Bitmap object used to track pages in the input database. Allocated
121 ** and manipulated only by the following functions:
122 **
123 **     recoverBitmapAlloc()
124 **     recoverBitmapFree()
125 **     recoverBitmapSet()
126 **     recoverBitmapQuery()
127 **
128 ** nPg:
129 **   Largest page number that may be stored in the bitmap. The range
130 **   of valid keys is 1 to nPg, inclusive.
131 **
132 ** aElem[]:
133 **   Array large enough to contain a bit for each key. For key value
134 **   iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32].
135 **   In other words, the following is true if bit iKey is set, or
136 **   false if it is clear:
137 **
138 **       (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0
139 */
140 typedef struct RecoverBitmap RecoverBitmap;
141 struct RecoverBitmap {
142   i64 nPg;                        /* Size of bitmap */
143   u32 aElem[1];                   /* Array of 32-bit bitmasks */
144 };
145 
146 /*
147 ** State variables (part of the sqlite3_recover structure) used while
148 ** recovering data for tables identified in the recovered schema (state
149 ** RECOVER_STATE_WRITING).
150 */
151 typedef struct RecoverStateW1 RecoverStateW1;
152 struct RecoverStateW1 {
153   sqlite3_stmt *pTbls;
154   sqlite3_stmt *pSel;
155   sqlite3_stmt *pInsert;
156   int nInsert;
157 
158   RecoverTable *pTab;             /* Table currently being written */
159   int nMax;                       /* Max column count in any schema table */
160   sqlite3_value **apVal;          /* Array of nMax values */
161   int nVal;                       /* Number of valid entries in apVal[] */
162   int bHaveRowid;
163   i64 iRowid;
164   i64 iPrevPage;
165   int iPrevCell;
166 };
167 
168 /*
169 ** State variables (part of the sqlite3_recover structure) used while
170 ** recovering data destined for the lost and found table (states
171 ** RECOVER_STATE_LOSTANDFOUND[123]).
172 */
173 typedef struct RecoverStateLAF RecoverStateLAF;
174 struct RecoverStateLAF {
175   RecoverBitmap *pUsed;
176   i64 nPg;                        /* Size of db in pages */
177   sqlite3_stmt *pAllAndParent;
178   sqlite3_stmt *pMapInsert;
179   sqlite3_stmt *pMaxField;
180   sqlite3_stmt *pUsedPages;
181   sqlite3_stmt *pFindRoot;
182   sqlite3_stmt *pInsert;          /* INSERT INTO lost_and_found ... */
183   sqlite3_stmt *pAllPage;
184   sqlite3_stmt *pPageData;
185   sqlite3_value **apVal;
186   int nMaxField;
187 };
188 
189 /*
190 ** Main recover handle structure.
191 */
192 struct sqlite3_recover {
193   /* Copies of sqlite3_recover_init[_sql]() parameters */
194   sqlite3 *dbIn;                  /* Input database */
195   char *zDb;                      /* Name of input db ("main" etc.) */
196   char *zUri;                     /* URI for output database */
197   void *pSqlCtx;                  /* SQL callback context */
198   int (*xSql)(void*,const char*); /* Pointer to SQL callback function */
199 
200   /* Values configured by sqlite3_recover_config() */
201   char *zStateDb;                 /* State database to use (or NULL) */
202   char *zLostAndFound;            /* Name of lost-and-found table (or NULL) */
203   int bFreelistCorrupt;           /* SQLITE_RECOVER_FREELIST_CORRUPT setting */
204   int bRecoverRowid;              /* SQLITE_RECOVER_ROWIDS setting */
205   int bSlowIndexes;               /* SQLITE_RECOVER_SLOWINDEXES setting */
206 
207   int pgsz;
208   int detected_pgsz;
209   int nReserve;
210   u8 *pPage1Disk;
211   u8 *pPage1Cache;
212 
213   /* Error code and error message */
214   int errCode;                    /* For sqlite3_recover_errcode() */
215   char *zErrMsg;                  /* For sqlite3_recover_errmsg() */
216 
217   int eState;
218   int bCloseTransaction;
219 
220   /* Variables used with eState==RECOVER_STATE_WRITING */
221   RecoverStateW1 w1;
222 
223   /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */
224   RecoverStateLAF laf;
225 
226   /* Fields used within sqlite3_recover_run() */
227   sqlite3 *dbOut;                 /* Output database */
228   sqlite3_stmt *pGetPage;         /* SELECT against input db sqlite_dbdata */
229   RecoverTable *pTblList;         /* List of tables recovered from schema */
230 };
231 
232 /*
233 ** The various states in which an sqlite3_recover object may exist:
234 **
235 **   RECOVER_STATE_INIT:
236 **    The object is initially created in this state. sqlite3_recover_step()
237 **    has yet to be called. This is the only state in which it is permitted
238 **    to call sqlite3_recover_config().
239 **
240 **   RECOVER_STATE_WRITING:
241 **
242 **   RECOVER_STATE_LOSTANDFOUND1:
243 **    State to populate the bitmap of pages used by other tables or the
244 **    database freelist.
245 **
246 **   RECOVER_STATE_LOSTANDFOUND2:
247 **    Populate the recovery.map table - used to figure out a "root" page
248 **    for each lost page from in the database from which records are
249 **    extracted.
250 **
251 **   RECOVER_STATE_LOSTANDFOUND3:
252 **    Populate the lost-and-found table itself.
253 */
254 #define RECOVER_STATE_INIT           0
255 #define RECOVER_STATE_WRITING        1
256 #define RECOVER_STATE_LOSTANDFOUND1  2
257 #define RECOVER_STATE_LOSTANDFOUND2  3
258 #define RECOVER_STATE_LOSTANDFOUND3  4
259 #define RECOVER_STATE_SCHEMA2        5
260 #define RECOVER_STATE_DONE           6
261 
262 
263 /*
264 ** Global variables used by this extension.
265 */
266 typedef struct RecoverGlobal RecoverGlobal;
267 struct RecoverGlobal {
268   const sqlite3_io_methods *pMethods;
269   sqlite3_recover *p;
270 };
271 static RecoverGlobal recover_g;
272 
273 /*
274 ** Use this static SQLite mutex to protect the globals during the
275 ** first call to sqlite3_recover_step().
276 */
277 #define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2
278 
279 
280 /*
281 ** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid).
282 */
283 #define RECOVER_ROWID_DEFAULT 1
284 
285 /*
286 ** Mutex handling:
287 **
288 **    recoverEnterMutex()       -   Enter the recovery mutex
289 **    recoverLeaveMutex()       -   Leave the recovery mutex
290 **    recoverAssertMutexHeld()  -   Assert that the recovery mutex is held
291 */
292 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
293 # define recoverEnterMutex()
294 # define recoverLeaveMutex()
295 #else
recoverEnterMutex(void)296 static void recoverEnterMutex(void){
297   sqlite3_mutex_enter(sqlite3_mutex_alloc(RECOVER_MUTEX_ID));
298 }
recoverLeaveMutex(void)299 static void recoverLeaveMutex(void){
300   sqlite3_mutex_leave(sqlite3_mutex_alloc(RECOVER_MUTEX_ID));
301 }
302 #endif
303 #if SQLITE_THREADSAFE+0>=1 && defined(SQLITE_DEBUG)
recoverAssertMutexHeld(void)304 static void recoverAssertMutexHeld(void){
305   assert( sqlite3_mutex_held(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)) );
306 }
307 #else
308 # define recoverAssertMutexHeld()
309 #endif
310 
311 
312 /*
313 ** Like strlen(). But handles NULL pointer arguments.
314 */
recoverStrlen(const char * zStr)315 static int recoverStrlen(const char *zStr){
316   if( zStr==0 ) return 0;
317   return (int)(strlen(zStr)&0x7fffffff);
318 }
319 
320 /*
321 ** This function is a no-op if the recover handle passed as the first
322 ** argument already contains an error (if p->errCode!=SQLITE_OK).
323 **
324 ** Otherwise, an attempt is made to allocate, zero and return a buffer nByte
325 ** bytes in size. If successful, a pointer to the new buffer is returned. Or,
326 ** if an OOM error occurs, NULL is returned and the handle error code
327 ** (p->errCode) set to SQLITE_NOMEM.
328 */
recoverMalloc(sqlite3_recover * p,i64 nByte)329 static void *recoverMalloc(sqlite3_recover *p, i64 nByte){
330   void *pRet = 0;
331   assert( nByte>0 );
332   if( p->errCode==SQLITE_OK ){
333     pRet = sqlite3_malloc64(nByte);
334     if( pRet ){
335       memset(pRet, 0, nByte);
336     }else{
337       p->errCode = SQLITE_NOMEM;
338     }
339   }
340   return pRet;
341 }
342 
343 /*
344 ** Set the error code and error message for the recover handle passed as
345 ** the first argument. The error code is set to the value of parameter
346 ** errCode.
347 **
348 ** Parameter zFmt must be a printf() style formatting string. The handle
349 ** error message is set to the result of using any trailing arguments for
350 ** parameter substitutions in the formatting string.
351 **
352 ** For example:
353 **
354 **   recoverError(p, SQLITE_ERROR, "no such table: %s", zTablename);
355 */
recoverError(sqlite3_recover * p,int errCode,const char * zFmt,...)356 static int recoverError(
357   sqlite3_recover *p,
358   int errCode,
359   const char *zFmt, ...
360 ){
361   char *z = 0;
362   va_list ap;
363   va_start(ap, zFmt);
364   if( zFmt ){
365     z = sqlite3_vmprintf(zFmt, ap);
366     va_end(ap);
367   }
368   sqlite3_free(p->zErrMsg);
369   p->zErrMsg = z;
370   p->errCode = errCode;
371   return errCode;
372 }
373 
374 
375 /*
376 ** This function is a no-op if p->errCode is initially other than SQLITE_OK.
377 ** In this case it returns NULL.
378 **
379 ** Otherwise, an attempt is made to allocate and return a bitmap object
380 ** large enough to store a bit for all page numbers between 1 and nPg,
381 ** inclusive. The bitmap is initially zeroed.
382 */
recoverBitmapAlloc(sqlite3_recover * p,i64 nPg)383 static RecoverBitmap *recoverBitmapAlloc(sqlite3_recover *p, i64 nPg){
384   int nElem = (nPg+1+31) / 32;
385   int nByte = sizeof(RecoverBitmap) + nElem*sizeof(u32);
386   RecoverBitmap *pRet = (RecoverBitmap*)recoverMalloc(p, nByte);
387 
388   if( pRet ){
389     pRet->nPg = nPg;
390   }
391   return pRet;
392 }
393 
394 /*
395 ** Free a bitmap object allocated by recoverBitmapAlloc().
396 */
recoverBitmapFree(RecoverBitmap * pMap)397 static void recoverBitmapFree(RecoverBitmap *pMap){
398   sqlite3_free(pMap);
399 }
400 
401 /*
402 ** Set the bit associated with page iPg in bitvec pMap.
403 */
recoverBitmapSet(RecoverBitmap * pMap,i64 iPg)404 static void recoverBitmapSet(RecoverBitmap *pMap, i64 iPg){
405   if( iPg<=pMap->nPg ){
406     int iElem = (iPg / 32);
407     int iBit = (iPg % 32);
408     pMap->aElem[iElem] |= (((u32)1) << iBit);
409   }
410 }
411 
412 /*
413 ** Query bitmap object pMap for the state of the bit associated with page
414 ** iPg. Return 1 if it is set, or 0 otherwise.
415 */
recoverBitmapQuery(RecoverBitmap * pMap,i64 iPg)416 static int recoverBitmapQuery(RecoverBitmap *pMap, i64 iPg){
417   int ret = 1;
418   if( iPg<=pMap->nPg && iPg>0 ){
419     int iElem = (iPg / 32);
420     int iBit = (iPg % 32);
421     ret = (pMap->aElem[iElem] & (((u32)1) << iBit)) ? 1 : 0;
422   }
423   return ret;
424 }
425 
426 /*
427 ** Set the recover handle error to the error code and message returned by
428 ** calling sqlite3_errcode() and sqlite3_errmsg(), respectively, on database
429 ** handle db.
430 */
recoverDbError(sqlite3_recover * p,sqlite3 * db)431 static int recoverDbError(sqlite3_recover *p, sqlite3 *db){
432   return recoverError(p, sqlite3_errcode(db), "%s", sqlite3_errmsg(db));
433 }
434 
435 /*
436 ** This function is a no-op if recover handle p already contains an error
437 ** (if p->errCode!=SQLITE_OK).
438 **
439 ** Otherwise, it attempts to prepare the SQL statement in zSql against
440 ** database handle db. If successful, the statement handle is returned.
441 ** Or, if an error occurs, NULL is returned and an error left in the
442 ** recover handle.
443 */
recoverPrepare(sqlite3_recover * p,sqlite3 * db,const char * zSql)444 static sqlite3_stmt *recoverPrepare(
445   sqlite3_recover *p,
446   sqlite3 *db,
447   const char *zSql
448 ){
449   sqlite3_stmt *pStmt = 0;
450   if( p->errCode==SQLITE_OK ){
451     if( sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) ){
452       recoverDbError(p, db);
453     }
454   }
455   return pStmt;
456 }
457 
458 /*
459 ** This function is a no-op if recover handle p already contains an error
460 ** (if p->errCode!=SQLITE_OK).
461 **
462 ** Otherwise, argument zFmt is used as a printf() style format string,
463 ** along with any trailing arguments, to create an SQL statement. This
464 ** SQL statement is prepared against database handle db and, if successful,
465 ** the statment handle returned. Or, if an error occurs - either during
466 ** the printf() formatting or when preparing the resulting SQL - an
467 ** error code and message are left in the recover handle.
468 */
recoverPreparePrintf(sqlite3_recover * p,sqlite3 * db,const char * zFmt,...)469 static sqlite3_stmt *recoverPreparePrintf(
470   sqlite3_recover *p,
471   sqlite3 *db,
472   const char *zFmt, ...
473 ){
474   sqlite3_stmt *pStmt = 0;
475   if( p->errCode==SQLITE_OK ){
476     va_list ap;
477     char *z;
478     va_start(ap, zFmt);
479     z = sqlite3_vmprintf(zFmt, ap);
480     va_end(ap);
481     if( z==0 ){
482       p->errCode = SQLITE_NOMEM;
483     }else{
484       pStmt = recoverPrepare(p, db, z);
485       sqlite3_free(z);
486     }
487   }
488   return pStmt;
489 }
490 
491 /*
492 ** Reset SQLite statement handle pStmt. If the call to sqlite3_reset()
493 ** indicates that an error occurred, and there is not already an error
494 ** in the recover handle passed as the first argument, set the error
495 ** code and error message appropriately.
496 **
497 ** This function returns a copy of the statement handle pointer passed
498 ** as the second argument.
499 */
recoverReset(sqlite3_recover * p,sqlite3_stmt * pStmt)500 static sqlite3_stmt *recoverReset(sqlite3_recover *p, sqlite3_stmt *pStmt){
501   int rc = sqlite3_reset(pStmt);
502   if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT && p->errCode==SQLITE_OK ){
503     recoverDbError(p, sqlite3_db_handle(pStmt));
504   }
505   return pStmt;
506 }
507 
508 /*
509 ** Finalize SQLite statement handle pStmt. If the call to sqlite3_reset()
510 ** indicates that an error occurred, and there is not already an error
511 ** in the recover handle passed as the first argument, set the error
512 ** code and error message appropriately.
513 */
recoverFinalize(sqlite3_recover * p,sqlite3_stmt * pStmt)514 static void recoverFinalize(sqlite3_recover *p, sqlite3_stmt *pStmt){
515   sqlite3 *db = sqlite3_db_handle(pStmt);
516   int rc = sqlite3_finalize(pStmt);
517   if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){
518     recoverDbError(p, db);
519   }
520 }
521 
522 /*
523 ** This function is a no-op if recover handle p already contains an error
524 ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this
525 ** case.
526 **
527 ** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK.
528 ** Or, if an error occurs, leave an error code and message in the recover
529 ** handle and return a copy of the error code.
530 */
recoverExec(sqlite3_recover * p,sqlite3 * db,const char * zSql)531 static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){
532   if( p->errCode==SQLITE_OK ){
533     int rc = sqlite3_exec(db, zSql, 0, 0, 0);
534     if( rc ){
535       recoverDbError(p, db);
536     }
537   }
538   return p->errCode;
539 }
540 
541 /*
542 ** Bind the value pVal to parameter iBind of statement pStmt. Leave an
543 ** error in the recover handle passed as the first argument if an error
544 ** (e.g. an OOM) occurs.
545 */
recoverBindValue(sqlite3_recover * p,sqlite3_stmt * pStmt,int iBind,sqlite3_value * pVal)546 static void recoverBindValue(
547   sqlite3_recover *p,
548   sqlite3_stmt *pStmt,
549   int iBind,
550   sqlite3_value *pVal
551 ){
552   if( p->errCode==SQLITE_OK ){
553     int rc = sqlite3_bind_value(pStmt, iBind, pVal);
554     if( rc ) recoverError(p, rc, 0);
555   }
556 }
557 
558 /*
559 ** This function is a no-op if recover handle p already contains an error
560 ** (if p->errCode!=SQLITE_OK). NULL is returned in this case.
561 **
562 ** Otherwise, an attempt is made to interpret zFmt as a printf() style
563 ** formatting string and the result of using the trailing arguments for
564 ** parameter substitution with it written into a buffer obtained from
565 ** sqlite3_malloc(). If successful, a pointer to the buffer is returned.
566 ** It is the responsibility of the caller to eventually free the buffer
567 ** using sqlite3_free().
568 **
569 ** Or, if an error occurs, an error code and message is left in the recover
570 ** handle and NULL returned.
571 */
recoverMPrintf(sqlite3_recover * p,const char * zFmt,...)572 static char *recoverMPrintf(sqlite3_recover *p, const char *zFmt, ...){
573   va_list ap;
574   char *z;
575   va_start(ap, zFmt);
576   z = sqlite3_vmprintf(zFmt, ap);
577   va_end(ap);
578   if( p->errCode==SQLITE_OK ){
579     if( z==0 ) p->errCode = SQLITE_NOMEM;
580   }else{
581     sqlite3_free(z);
582     z = 0;
583   }
584   return z;
585 }
586 
587 /*
588 ** This function is a no-op if recover handle p already contains an error
589 ** (if p->errCode!=SQLITE_OK). Zero is returned in this case.
590 **
591 ** Otherwise, execute "PRAGMA page_count" against the input database. If
592 ** successful, return the integer result. Or, if an error occurs, leave an
593 ** error code and error message in the sqlite3_recover handle and return
594 ** zero.
595 */
recoverPageCount(sqlite3_recover * p)596 static i64 recoverPageCount(sqlite3_recover *p){
597   i64 nPg = 0;
598   if( p->errCode==SQLITE_OK ){
599     sqlite3_stmt *pStmt = 0;
600     pStmt = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.page_count", p->zDb);
601     if( pStmt ){
602       sqlite3_step(pStmt);
603       nPg = sqlite3_column_int64(pStmt, 0);
604     }
605     recoverFinalize(p, pStmt);
606   }
607   return nPg;
608 }
609 
610 /*
611 ** Implementation of SQL scalar function "read_i32". The first argument to
612 ** this function must be a blob. The second a non-negative integer. This
613 ** function reads and returns a 32-bit big-endian integer from byte
614 ** offset (4*<arg2>) of the blob.
615 **
616 **     SELECT read_i32(<blob>, <idx>)
617 */
recoverReadI32(sqlite3_context * context,int argc,sqlite3_value ** argv)618 static void recoverReadI32(
619   sqlite3_context *context,
620   int argc,
621   sqlite3_value **argv
622 ){
623   const unsigned char *pBlob;
624   int nBlob;
625   int iInt;
626 
627   assert( argc==2 );
628   nBlob = sqlite3_value_bytes(argv[0]);
629   pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
630   iInt = sqlite3_value_int(argv[1]) & 0xFFFF;
631 
632   if( (iInt+1)*4<=nBlob ){
633     const unsigned char *a = &pBlob[iInt*4];
634     i64 iVal = ((i64)a[0]<<24)
635              + ((i64)a[1]<<16)
636              + ((i64)a[2]<< 8)
637              + ((i64)a[3]<< 0);
638     sqlite3_result_int64(context, iVal);
639   }
640 }
641 
642 /*
643 ** Implementation of SQL scalar function "page_is_used". This function
644 ** is used as part of the procedure for locating orphan rows for the
645 ** lost-and-found table, and it depends on those routines having populated
646 ** the sqlite3_recover.laf.pUsed variable.
647 **
648 ** The only argument to this function is a page-number. It returns true
649 ** if the page has already been used somehow during data recovery, or false
650 ** otherwise.
651 **
652 **     SELECT page_is_used(<pgno>);
653 */
recoverPageIsUsed(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)654 static void recoverPageIsUsed(
655   sqlite3_context *pCtx,
656   int nArg,
657   sqlite3_value **apArg
658 ){
659   sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx);
660   i64 pgno = sqlite3_value_int64(apArg[0]);
661   assert( nArg==1 );
662   sqlite3_result_int(pCtx, recoverBitmapQuery(p->laf.pUsed, pgno));
663 }
664 
665 /*
666 ** The implementation of a user-defined SQL function invoked by the
667 ** sqlite_dbdata and sqlite_dbptr virtual table modules to access pages
668 ** of the database being recovered.
669 **
670 ** This function always takes a single integer argument. If the argument
671 ** is zero, then the value returned is the number of pages in the db being
672 ** recovered. If the argument is greater than zero, it is a page number.
673 ** The value returned in this case is an SQL blob containing the data for
674 ** the identified page of the db being recovered. e.g.
675 **
676 **     SELECT getpage(0);       -- return number of pages in db
677 **     SELECT getpage(4);       -- return page 4 of db as a blob of data
678 */
recoverGetPage(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)679 static void recoverGetPage(
680   sqlite3_context *pCtx,
681   int nArg,
682   sqlite3_value **apArg
683 ){
684   sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx);
685   i64 pgno = sqlite3_value_int64(apArg[0]);
686   sqlite3_stmt *pStmt = 0;
687 
688   assert( nArg==1 );
689   if( pgno==0 ){
690     i64 nPg = recoverPageCount(p);
691     sqlite3_result_int64(pCtx, nPg);
692     return;
693   }else{
694     if( p->pGetPage==0 ){
695       pStmt = p->pGetPage = recoverPreparePrintf(
696           p, p->dbIn, "SELECT data FROM sqlite_dbpage(%Q) WHERE pgno=?", p->zDb
697       );
698     }else if( p->errCode==SQLITE_OK ){
699       pStmt = p->pGetPage;
700     }
701 
702     if( pStmt ){
703       sqlite3_bind_int64(pStmt, 1, pgno);
704       if( SQLITE_ROW==sqlite3_step(pStmt) ){
705         const u8 *aPg;
706         int nPg;
707         assert( p->errCode==SQLITE_OK );
708         aPg = sqlite3_column_blob(pStmt, 0);
709         nPg = sqlite3_column_bytes(pStmt, 0);
710         if( pgno==1 && nPg==p->pgsz && 0==memcmp(p->pPage1Cache, aPg, nPg) ){
711           aPg = p->pPage1Disk;
712         }
713         sqlite3_result_blob(pCtx, aPg, nPg-p->nReserve, SQLITE_TRANSIENT);
714       }
715       recoverReset(p, pStmt);
716     }
717   }
718 
719   if( p->errCode ){
720     if( p->zErrMsg ) sqlite3_result_error(pCtx, p->zErrMsg, -1);
721     sqlite3_result_error_code(pCtx, p->errCode);
722   }
723 }
724 
725 /*
726 ** Find a string that is not found anywhere in z[].  Return a pointer
727 ** to that string.
728 **
729 ** Try to use zA and zB first.  If both of those are already found in z[]
730 ** then make up some string and store it in the buffer zBuf.
731 */
recoverUnusedString(const char * z,const char * zA,const char * zB,char * zBuf)732 static const char *recoverUnusedString(
733   const char *z,                    /* Result must not appear anywhere in z */
734   const char *zA, const char *zB,   /* Try these first */
735   char *zBuf                        /* Space to store a generated string */
736 ){
737   unsigned i = 0;
738   if( strstr(z, zA)==0 ) return zA;
739   if( strstr(z, zB)==0 ) return zB;
740   do{
741     sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
742   }while( strstr(z,zBuf)!=0 );
743   return zBuf;
744 }
745 
746 /*
747 ** Implementation of scalar SQL function "escape_crnl".  The argument passed to
748 ** this function is the output of built-in function quote(). If the first
749 ** character of the input is "'", indicating that the value passed to quote()
750 ** was a text value, then this function searches the input for "\n" and "\r"
751 ** characters and adds a wrapper similar to the following:
752 **
753 **   replace(replace(<input>, '\n', char(10), '\r', char(13));
754 **
755 ** Or, if the first character of the input is not "'", then a copy of the input
756 ** is returned.
757 */
recoverEscapeCrnl(sqlite3_context * context,int argc,sqlite3_value ** argv)758 static void recoverEscapeCrnl(
759   sqlite3_context *context,
760   int argc,
761   sqlite3_value **argv
762 ){
763   const char *zText = (const char*)sqlite3_value_text(argv[0]);
764   if( zText && zText[0]=='\'' ){
765     int nText = sqlite3_value_bytes(argv[0]);
766     int i;
767     char zBuf1[20];
768     char zBuf2[20];
769     const char *zNL = 0;
770     const char *zCR = 0;
771     int nCR = 0;
772     int nNL = 0;
773 
774     for(i=0; zText[i]; i++){
775       if( zNL==0 && zText[i]=='\n' ){
776         zNL = recoverUnusedString(zText, "\\n", "\\012", zBuf1);
777         nNL = (int)strlen(zNL);
778       }
779       if( zCR==0 && zText[i]=='\r' ){
780         zCR = recoverUnusedString(zText, "\\r", "\\015", zBuf2);
781         nCR = (int)strlen(zCR);
782       }
783     }
784 
785     if( zNL || zCR ){
786       int iOut = 0;
787       i64 nMax = (nNL > nCR) ? nNL : nCR;
788       i64 nAlloc = nMax * nText + (nMax+64)*2;
789       char *zOut = (char*)sqlite3_malloc64(nAlloc);
790       if( zOut==0 ){
791         sqlite3_result_error_nomem(context);
792         return;
793       }
794 
795       if( zNL && zCR ){
796         memcpy(&zOut[iOut], "replace(replace(", 16);
797         iOut += 16;
798       }else{
799         memcpy(&zOut[iOut], "replace(", 8);
800         iOut += 8;
801       }
802       for(i=0; zText[i]; i++){
803         if( zText[i]=='\n' ){
804           memcpy(&zOut[iOut], zNL, nNL);
805           iOut += nNL;
806         }else if( zText[i]=='\r' ){
807           memcpy(&zOut[iOut], zCR, nCR);
808           iOut += nCR;
809         }else{
810           zOut[iOut] = zText[i];
811           iOut++;
812         }
813       }
814 
815       if( zNL ){
816         memcpy(&zOut[iOut], ",'", 2); iOut += 2;
817         memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
818         memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
819       }
820       if( zCR ){
821         memcpy(&zOut[iOut], ",'", 2); iOut += 2;
822         memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
823         memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
824       }
825 
826       sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
827       sqlite3_free(zOut);
828       return;
829     }
830   }
831 
832   sqlite3_result_value(context, argv[0]);
833 }
834 
835 /*
836 ** This function is a no-op if recover handle p already contains an error
837 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
838 ** this case.
839 **
840 ** Otherwise, attempt to populate temporary table "recovery.schema" with the
841 ** parts of the database schema that can be extracted from the input database.
842 **
843 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
844 ** and error message are left in the recover handle and a copy of the
845 ** error code returned. It is not considered an error if part of all of
846 ** the database schema cannot be recovered due to corruption.
847 */
recoverCacheSchema(sqlite3_recover * p)848 static int recoverCacheSchema(sqlite3_recover *p){
849   return recoverExec(p, p->dbOut,
850     "WITH RECURSIVE pages(p) AS ("
851     "  SELECT 1"
852     "    UNION"
853     "  SELECT child FROM sqlite_dbptr('getpage()'), pages WHERE pgno=p"
854     ")"
855     "INSERT INTO recovery.schema SELECT"
856     "  max(CASE WHEN field=0 THEN value ELSE NULL END),"
857     "  max(CASE WHEN field=1 THEN value ELSE NULL END),"
858     "  max(CASE WHEN field=2 THEN value ELSE NULL END),"
859     "  max(CASE WHEN field=3 THEN value ELSE NULL END),"
860     "  max(CASE WHEN field=4 THEN value ELSE NULL END)"
861     "FROM sqlite_dbdata('getpage()') WHERE pgno IN ("
862     "  SELECT p FROM pages"
863     ") GROUP BY pgno, cell"
864   );
865 }
866 
867 /*
868 ** If this recover handle is not in SQL callback mode (i.e. was not created
869 ** using sqlite3_recover_init_sql()) of if an error has already occurred,
870 ** this function is a no-op. Otherwise, issue a callback with SQL statement
871 ** zSql as the parameter.
872 **
873 ** If the callback returns non-zero, set the recover handle error code to
874 ** the value returned (so that the caller will abandon processing).
875 */
recoverSqlCallback(sqlite3_recover * p,const char * zSql)876 static void recoverSqlCallback(sqlite3_recover *p, const char *zSql){
877   if( p->errCode==SQLITE_OK && p->xSql ){
878     int res = p->xSql(p->pSqlCtx, zSql);
879     if( res ){
880       recoverError(p, SQLITE_ERROR, "callback returned an error - %d", res);
881     }
882   }
883 }
884 
885 /*
886 ** Transfer the following settings from the input database to the output
887 ** database:
888 **
889 **   + page-size,
890 **   + auto-vacuum settings,
891 **   + database encoding,
892 **   + user-version (PRAGMA user_version), and
893 **   + application-id (PRAGMA application_id), and
894 */
recoverTransferSettings(sqlite3_recover * p)895 static void recoverTransferSettings(sqlite3_recover *p){
896   const char *aPragma[] = {
897     "encoding",
898     "page_size",
899     "auto_vacuum",
900     "user_version",
901     "application_id"
902   };
903   int ii;
904 
905   /* Truncate the output database to 0 pages in size. This is done by
906   ** opening a new, empty, temp db, then using the backup API to clobber
907   ** any existing output db with a copy of it. */
908   if( p->errCode==SQLITE_OK ){
909     sqlite3 *db2 = 0;
910     int rc = sqlite3_open("", &db2);
911     if( rc!=SQLITE_OK ){
912       recoverDbError(p, db2);
913       return;
914     }
915 
916     for(ii=0; ii<sizeof(aPragma)/sizeof(aPragma[0]); ii++){
917       const char *zPrag = aPragma[ii];
918       sqlite3_stmt *p1 = 0;
919       p1 = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.%s", p->zDb, zPrag);
920       if( p->errCode==SQLITE_OK && sqlite3_step(p1)==SQLITE_ROW ){
921         const char *zArg = (const char*)sqlite3_column_text(p1, 0);
922         char *z2 = recoverMPrintf(p, "PRAGMA %s = %Q", zPrag, zArg);
923         recoverSqlCallback(p, z2);
924         recoverExec(p, db2, z2);
925         sqlite3_free(z2);
926         if( zArg==0 ){
927           recoverError(p, SQLITE_NOMEM, 0);
928         }
929       }
930       recoverFinalize(p, p1);
931     }
932     recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;");
933 
934     if( p->errCode==SQLITE_OK ){
935       sqlite3 *db = p->dbOut;
936       sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main");
937       if( pBackup ){
938         sqlite3_backup_step(pBackup, -1);
939         p->errCode = sqlite3_backup_finish(pBackup);
940       }else{
941         recoverDbError(p, db);
942       }
943     }
944 
945     sqlite3_close(db2);
946   }
947 }
948 
949 /*
950 ** This function is a no-op if recover handle p already contains an error
951 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
952 ** this case.
953 **
954 ** Otherwise, an attempt is made to open the output database, attach
955 ** and create the schema of the temporary database used to store
956 ** intermediate data, and to register all required user functions and
957 ** virtual table modules with the output handle.
958 **
959 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
960 ** and error message are left in the recover handle and a copy of the
961 ** error code returned.
962 */
recoverOpenOutput(sqlite3_recover * p)963 static int recoverOpenOutput(sqlite3_recover *p){
964   struct Func {
965     const char *zName;
966     int nArg;
967     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
968   } aFunc[] = {
969     { "getpage", 1, recoverGetPage },
970     { "page_is_used", 1, recoverPageIsUsed },
971     { "read_i32", 2, recoverReadI32 },
972     { "escape_crnl", 1, recoverEscapeCrnl },
973   };
974 
975   const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
976   sqlite3 *db = 0;                /* New database handle */
977   int ii;                         /* For iterating through aFunc[] */
978 
979   assert( p->dbOut==0 );
980 
981   if( sqlite3_open_v2(p->zUri, &db, flags, 0) ){
982     recoverDbError(p, db);
983   }
984 
985   /* Register the sqlite_dbdata and sqlite_dbptr virtual table modules.
986   ** These two are registered with the output database handle - this
987   ** module depends on the input handle supporting the sqlite_dbpage
988   ** virtual table only.  */
989   if( p->errCode==SQLITE_OK ){
990     p->errCode = sqlite3_dbdata_init(db, 0, 0);
991   }
992 
993   /* Register the custom user-functions with the output handle. */
994   for(ii=0; p->errCode==SQLITE_OK && ii<sizeof(aFunc)/sizeof(aFunc[0]); ii++){
995     p->errCode = sqlite3_create_function(db, aFunc[ii].zName,
996         aFunc[ii].nArg, SQLITE_UTF8, (void*)p, aFunc[ii].xFunc, 0, 0
997     );
998   }
999 
1000   p->dbOut = db;
1001   return p->errCode;
1002 }
1003 
1004 /*
1005 ** Attach the auxiliary database 'recovery' to the output database handle.
1006 ** This temporary database is used during the recovery process and then
1007 ** discarded.
1008 */
recoverOpenRecovery(sqlite3_recover * p)1009 static void recoverOpenRecovery(sqlite3_recover *p){
1010   char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb);
1011   recoverExec(p, p->dbOut, zSql);
1012   recoverExec(p, p->dbOut,
1013       "PRAGMA writable_schema = 1;"
1014       "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);"
1015       "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
1016   );
1017   sqlite3_free(zSql);
1018 }
1019 
1020 
1021 /*
1022 ** This function is a no-op if recover handle p already contains an error
1023 ** (if p->errCode!=SQLITE_OK).
1024 **
1025 ** Otherwise, argument zName must be the name of a table that has just been
1026 ** created in the output database. This function queries the output db
1027 ** for the schema of said table, and creates a RecoverTable object to
1028 ** store the schema in memory. The new RecoverTable object is linked into
1029 ** the list at sqlite3_recover.pTblList.
1030 **
1031 ** Parameter iRoot must be the root page of table zName in the INPUT
1032 ** database.
1033 */
recoverAddTable(sqlite3_recover * p,const char * zName,i64 iRoot)1034 static void recoverAddTable(
1035   sqlite3_recover *p,
1036   const char *zName,              /* Name of table created in output db */
1037   i64 iRoot                       /* Root page of same table in INPUT db */
1038 ){
1039   sqlite3_stmt *pStmt = recoverPreparePrintf(p, p->dbOut,
1040       "PRAGMA table_xinfo(%Q)", zName
1041   );
1042 
1043   if( pStmt ){
1044     int iPk = -1;
1045     int iBind = 1;
1046     RecoverTable *pNew = 0;
1047     int nCol = 0;
1048     int nName = recoverStrlen(zName);
1049     int nByte = 0;
1050     while( sqlite3_step(pStmt)==SQLITE_ROW ){
1051       nCol++;
1052       nByte += (sqlite3_column_bytes(pStmt, 1)+1);
1053     }
1054     nByte += sizeof(RecoverTable) + nCol*sizeof(RecoverColumn) + nName+1;
1055     recoverReset(p, pStmt);
1056 
1057     pNew = recoverMalloc(p, nByte);
1058     if( pNew ){
1059       int i = 0;
1060       int iField = 0;
1061       char *csr = 0;
1062       pNew->aCol = (RecoverColumn*)&pNew[1];
1063       pNew->zTab = csr = (char*)&pNew->aCol[nCol];
1064       pNew->nCol = nCol;
1065       pNew->iRoot = iRoot;
1066       memcpy(csr, zName, nName);
1067       csr += nName+1;
1068 
1069       for(i=0; sqlite3_step(pStmt)==SQLITE_ROW; i++){
1070         int iPKF = sqlite3_column_int(pStmt, 5);
1071         int n = sqlite3_column_bytes(pStmt, 1);
1072         const char *z = (const char*)sqlite3_column_text(pStmt, 1);
1073         const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
1074         int eHidden = sqlite3_column_int(pStmt, 6);
1075 
1076         if( iPk==-1 && iPKF==1 && !sqlite3_stricmp("integer", zType) ) iPk = i;
1077         if( iPKF>1 ) iPk = -2;
1078         pNew->aCol[i].zCol = csr;
1079         pNew->aCol[i].eHidden = eHidden;
1080         if( eHidden==RECOVER_EHIDDEN_VIRTUAL ){
1081           pNew->aCol[i].iField = -1;
1082         }else{
1083           pNew->aCol[i].iField = iField++;
1084         }
1085         if( eHidden!=RECOVER_EHIDDEN_VIRTUAL
1086          && eHidden!=RECOVER_EHIDDEN_STORED
1087         ){
1088           pNew->aCol[i].iBind = iBind++;
1089         }
1090         memcpy(csr, z, n);
1091         csr += (n+1);
1092       }
1093 
1094       pNew->pNext = p->pTblList;
1095       p->pTblList = pNew;
1096       pNew->bIntkey = 1;
1097     }
1098 
1099     recoverFinalize(p, pStmt);
1100 
1101     pStmt = recoverPreparePrintf(p, p->dbOut, "PRAGMA index_xinfo(%Q)", zName);
1102     while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
1103       int iField = sqlite3_column_int(pStmt, 0);
1104       int iCol = sqlite3_column_int(pStmt, 1);
1105 
1106       assert( iField<pNew->nCol && iCol<pNew->nCol );
1107       pNew->aCol[iCol].iField = iField;
1108 
1109       pNew->bIntkey = 0;
1110       iPk = -2;
1111     }
1112     recoverFinalize(p, pStmt);
1113 
1114     if( p->errCode==SQLITE_OK ){
1115       if( iPk>=0 ){
1116         pNew->aCol[iPk].bIPK = 1;
1117       }else if( pNew->bIntkey ){
1118         pNew->iRowidBind = iBind++;
1119       }
1120     }
1121   }
1122 }
1123 
1124 /*
1125 ** This function is called after recoverCacheSchema() has cached those parts
1126 ** of the input database schema that could be recovered in temporary table
1127 ** "recovery.schema". This function creates in the output database copies
1128 ** of all parts of that schema that must be created before the tables can
1129 ** be populated. Specifically, this means:
1130 **
1131 **     * all tables that are not VIRTUAL, and
1132 **     * UNIQUE indexes.
1133 **
1134 ** If the recovery handle uses SQL callbacks, then callbacks containing
1135 ** the associated "CREATE TABLE" and "CREATE INDEX" statements are made.
1136 **
1137 ** Additionally, records are added to the sqlite_schema table of the
1138 ** output database for any VIRTUAL tables. The CREATE VIRTUAL TABLE
1139 ** records are written directly to sqlite_schema, not actually executed.
1140 ** If the handle is in SQL callback mode, then callbacks are invoked
1141 ** with equivalent SQL statements.
1142 */
recoverWriteSchema1(sqlite3_recover * p)1143 static int recoverWriteSchema1(sqlite3_recover *p){
1144   sqlite3_stmt *pSelect = 0;
1145   sqlite3_stmt *pTblname = 0;
1146 
1147   pSelect = recoverPrepare(p, p->dbOut,
1148       "WITH dbschema(rootpage, name, sql, tbl, isVirtual, isIndex) AS ("
1149       "  SELECT rootpage, name, sql, "
1150       "    type='table', "
1151       "    sql LIKE 'create virtual%',"
1152       "    (type='index' AND (sql LIKE '%unique%' OR ?1))"
1153       "  FROM recovery.schema"
1154       ")"
1155       "SELECT rootpage, tbl, isVirtual, name, sql"
1156       " FROM dbschema "
1157       "  WHERE tbl OR isIndex"
1158       "  ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
1159   );
1160 
1161   pTblname = recoverPrepare(p, p->dbOut,
1162       "SELECT name FROM sqlite_schema "
1163       "WHERE type='table' ORDER BY rowid DESC LIMIT 1"
1164   );
1165 
1166   if( pSelect ){
1167     sqlite3_bind_int(pSelect, 1, p->bSlowIndexes);
1168     while( sqlite3_step(pSelect)==SQLITE_ROW ){
1169       i64 iRoot = sqlite3_column_int64(pSelect, 0);
1170       int bTable = sqlite3_column_int(pSelect, 1);
1171       int bVirtual = sqlite3_column_int(pSelect, 2);
1172       const char *zName = (const char*)sqlite3_column_text(pSelect, 3);
1173       const char *zSql = (const char*)sqlite3_column_text(pSelect, 4);
1174       char *zFree = 0;
1175       int rc = SQLITE_OK;
1176 
1177       if( bVirtual ){
1178         zSql = (const char*)(zFree = recoverMPrintf(p,
1179             "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
1180             zName, zName, zSql
1181         ));
1182       }
1183       rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
1184       if( rc==SQLITE_OK ){
1185         recoverSqlCallback(p, zSql);
1186         if( bTable && !bVirtual ){
1187           if( SQLITE_ROW==sqlite3_step(pTblname) ){
1188             const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
1189             recoverAddTable(p, zTbl, iRoot);
1190           }
1191           recoverReset(p, pTblname);
1192         }
1193       }else if( rc!=SQLITE_ERROR ){
1194         recoverDbError(p, p->dbOut);
1195       }
1196       sqlite3_free(zFree);
1197     }
1198   }
1199   recoverFinalize(p, pSelect);
1200   recoverFinalize(p, pTblname);
1201 
1202   return p->errCode;
1203 }
1204 
1205 /*
1206 ** This function is called after the output database has been populated. It
1207 ** adds all recovered schema elements that were not created in the output
1208 ** database by recoverWriteSchema1() - everything except for tables and
1209 ** UNIQUE indexes. Specifically:
1210 **
1211 **     * views,
1212 **     * triggers,
1213 **     * non-UNIQUE indexes.
1214 **
1215 ** If the recover handle is in SQL callback mode, then equivalent callbacks
1216 ** are issued to create the schema elements.
1217 */
recoverWriteSchema2(sqlite3_recover * p)1218 static int recoverWriteSchema2(sqlite3_recover *p){
1219   sqlite3_stmt *pSelect = 0;
1220 
1221   pSelect = recoverPrepare(p, p->dbOut,
1222       p->bSlowIndexes ?
1223       "SELECT rootpage, sql FROM recovery.schema "
1224       "  WHERE type!='table' AND type!='index'"
1225       :
1226       "SELECT rootpage, sql FROM recovery.schema "
1227       "  WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
1228   );
1229 
1230   if( pSelect ){
1231     while( sqlite3_step(pSelect)==SQLITE_ROW ){
1232       const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
1233       int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
1234       if( rc==SQLITE_OK ){
1235         recoverSqlCallback(p, zSql);
1236       }else if( rc!=SQLITE_ERROR ){
1237         recoverDbError(p, p->dbOut);
1238       }
1239     }
1240   }
1241   recoverFinalize(p, pSelect);
1242 
1243   return p->errCode;
1244 }
1245 
1246 /*
1247 ** This function is a no-op if recover handle p already contains an error
1248 ** (if p->errCode!=SQLITE_OK). In this case it returns NULL.
1249 **
1250 ** Otherwise, if the recover handle is configured to create an output
1251 ** database (was created by sqlite3_recover_init()), then this function
1252 ** prepares and returns an SQL statement to INSERT a new record into table
1253 ** pTab, assuming the first nField fields of a record extracted from disk
1254 ** are valid.
1255 **
1256 ** For example, if table pTab is:
1257 **
1258 **     CREATE TABLE name(a, b GENERATED ALWAYS AS (a+1) STORED, c, d, e);
1259 **
1260 ** And nField is 4, then the SQL statement prepared and returned is:
1261 **
1262 **     INSERT INTO (a, c, d) VALUES (?1, ?2, ?3);
1263 **
1264 ** In this case even though 4 values were extracted from the input db,
1265 ** only 3 are written to the output, as the generated STORED column
1266 ** cannot be written.
1267 **
1268 ** If the recover handle is in SQL callback mode, then the SQL statement
1269 ** prepared is such that evaluating it returns a single row containing
1270 ** a single text value - itself an SQL statement similar to the above,
1271 ** except with SQL literals in place of the variables. For example:
1272 **
1273 **     SELECT 'INSERT INTO (a, c, d) VALUES ('
1274 **          || quote(?1) || ', '
1275 **          || quote(?2) || ', '
1276 **          || quote(?3) || ')';
1277 **
1278 ** In either case, it is the responsibility of the caller to eventually
1279 ** free the statement handle using sqlite3_finalize().
1280 */
recoverInsertStmt(sqlite3_recover * p,RecoverTable * pTab,int nField)1281 static sqlite3_stmt *recoverInsertStmt(
1282   sqlite3_recover *p,
1283   RecoverTable *pTab,
1284   int nField
1285 ){
1286   sqlite3_stmt *pRet = 0;
1287   const char *zSep = "";
1288   const char *zSqlSep = "";
1289   char *zSql = 0;
1290   char *zFinal = 0;
1291   char *zBind = 0;
1292   int ii;
1293   int bSql = p->xSql ? 1 : 0;
1294 
1295   if( nField<=0 ) return 0;
1296 
1297   assert( nField<=pTab->nCol );
1298 
1299   zSql = recoverMPrintf(p, "INSERT OR IGNORE INTO %Q(", pTab->zTab);
1300 
1301   if( pTab->iRowidBind ){
1302     assert( pTab->bIntkey );
1303     zSql = recoverMPrintf(p, "%z_rowid_", zSql);
1304     if( bSql ){
1305       zBind = recoverMPrintf(p, "%zquote(?%d)", zBind, pTab->iRowidBind);
1306     }else{
1307       zBind = recoverMPrintf(p, "%z?%d", zBind, pTab->iRowidBind);
1308     }
1309     zSqlSep = "||', '||";
1310     zSep = ", ";
1311   }
1312 
1313   for(ii=0; ii<nField; ii++){
1314     int eHidden = pTab->aCol[ii].eHidden;
1315     if( eHidden!=RECOVER_EHIDDEN_VIRTUAL
1316      && eHidden!=RECOVER_EHIDDEN_STORED
1317     ){
1318       assert( pTab->aCol[ii].iField>=0 && pTab->aCol[ii].iBind>=1 );
1319       zSql = recoverMPrintf(p, "%z%s%Q", zSql, zSep, pTab->aCol[ii].zCol);
1320 
1321       if( bSql ){
1322         zBind = recoverMPrintf(p,
1323             "%z%sescape_crnl(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind
1324         );
1325         zSqlSep = "||', '||";
1326       }else{
1327         zBind = recoverMPrintf(p, "%z%s?%d", zBind, zSep, pTab->aCol[ii].iBind);
1328       }
1329       zSep = ", ";
1330     }
1331   }
1332 
1333   if( bSql ){
1334     zFinal = recoverMPrintf(p, "SELECT %Q || ') VALUES (' || %s || ')'",
1335         zSql, zBind
1336     );
1337   }else{
1338     zFinal = recoverMPrintf(p, "%s) VALUES (%s)", zSql, zBind);
1339   }
1340 
1341   pRet = recoverPrepare(p, p->dbOut, zFinal);
1342   sqlite3_free(zSql);
1343   sqlite3_free(zBind);
1344   sqlite3_free(zFinal);
1345 
1346   return pRet;
1347 }
1348 
1349 
1350 /*
1351 ** Search the list of RecoverTable objects at p->pTblList for one that
1352 ** has root page iRoot in the input database. If such an object is found,
1353 ** return a pointer to it. Otherwise, return NULL.
1354 */
recoverFindTable(sqlite3_recover * p,u32 iRoot)1355 static RecoverTable *recoverFindTable(sqlite3_recover *p, u32 iRoot){
1356   RecoverTable *pRet = 0;
1357   for(pRet=p->pTblList; pRet && pRet->iRoot!=iRoot; pRet=pRet->pNext);
1358   return pRet;
1359 }
1360 
1361 /*
1362 ** This function attempts to create a lost and found table within the
1363 ** output db. If successful, it returns a pointer to a buffer containing
1364 ** the name of the new table. It is the responsibility of the caller to
1365 ** eventually free this buffer using sqlite3_free().
1366 **
1367 ** If an error occurs, NULL is returned and an error code and error
1368 ** message left in the recover handle.
1369 */
recoverLostAndFoundCreate(sqlite3_recover * p,int nField)1370 static char *recoverLostAndFoundCreate(
1371   sqlite3_recover *p,             /* Recover object */
1372   int nField                      /* Number of column fields in new table */
1373 ){
1374   char *zTbl = 0;
1375   sqlite3_stmt *pProbe = 0;
1376   int ii = 0;
1377 
1378   pProbe = recoverPrepare(p, p->dbOut,
1379     "SELECT 1 FROM sqlite_schema WHERE name=?"
1380   );
1381   for(ii=-1; zTbl==0 && p->errCode==SQLITE_OK && ii<1000; ii++){
1382     int bFail = 0;
1383     if( ii<0 ){
1384       zTbl = recoverMPrintf(p, "%s", p->zLostAndFound);
1385     }else{
1386       zTbl = recoverMPrintf(p, "%s_%d", p->zLostAndFound, ii);
1387     }
1388 
1389     if( p->errCode==SQLITE_OK ){
1390       sqlite3_bind_text(pProbe, 1, zTbl, -1, SQLITE_STATIC);
1391       if( SQLITE_ROW==sqlite3_step(pProbe) ){
1392         bFail = 1;
1393       }
1394       recoverReset(p, pProbe);
1395     }
1396 
1397     if( bFail ){
1398       sqlite3_clear_bindings(pProbe);
1399       sqlite3_free(zTbl);
1400       zTbl = 0;
1401     }
1402   }
1403   recoverFinalize(p, pProbe);
1404 
1405   if( zTbl ){
1406     const char *zSep = 0;
1407     char *zField = 0;
1408     char *zSql = 0;
1409 
1410     zSep = "rootpgno INTEGER, pgno INTEGER, nfield INTEGER, id INTEGER, ";
1411     for(ii=0; p->errCode==SQLITE_OK && ii<nField; ii++){
1412       zField = recoverMPrintf(p, "%z%sc%d", zField, zSep, ii);
1413       zSep = ", ";
1414     }
1415 
1416     zSql = recoverMPrintf(p, "CREATE TABLE %s(%s)", zTbl, zField);
1417     sqlite3_free(zField);
1418 
1419     recoverExec(p, p->dbOut, zSql);
1420     recoverSqlCallback(p, zSql);
1421     sqlite3_free(zSql);
1422   }else if( p->errCode==SQLITE_OK ){
1423     recoverError(
1424         p, SQLITE_ERROR, "failed to create %s output table", p->zLostAndFound
1425     );
1426   }
1427 
1428   return zTbl;
1429 }
1430 
1431 /*
1432 ** Synthesize and prepare an INSERT statement to write to the lost_and_found
1433 ** table in the output database. The name of the table is zTab, and it has
1434 ** nField c* fields.
1435 */
recoverLostAndFoundInsert(sqlite3_recover * p,const char * zTab,int nField)1436 static sqlite3_stmt *recoverLostAndFoundInsert(
1437   sqlite3_recover *p,
1438   const char *zTab,
1439   int nField
1440 ){
1441   int nTotal = nField + 4;
1442   int ii;
1443   char *zBind = 0;
1444   sqlite3_stmt *pRet = 0;
1445 
1446   if( p->xSql==0 ){
1447     for(ii=0; ii<nTotal; ii++){
1448       zBind = recoverMPrintf(p, "%z%s?", zBind, zBind?", ":"", ii);
1449     }
1450     pRet = recoverPreparePrintf(
1451         p, p->dbOut, "INSERT INTO %s VALUES(%s)", zTab, zBind
1452     );
1453   }else{
1454     const char *zSep = "";
1455     for(ii=0; ii<nTotal; ii++){
1456       zBind = recoverMPrintf(p, "%z%squote(?)", zBind, zSep);
1457       zSep = "|| ', ' ||";
1458     }
1459     pRet = recoverPreparePrintf(
1460         p, p->dbOut, "SELECT 'INSERT INTO %s VALUES(' || %s || ')'", zTab, zBind
1461     );
1462   }
1463 
1464   sqlite3_free(zBind);
1465   return pRet;
1466 }
1467 
1468 /*
1469 ** Input database page iPg contains data that will be written to the
1470 ** lost-and-found table of the output database. This function attempts
1471 ** to identify the root page of the tree that page iPg belonged to.
1472 ** If successful, it sets output variable (*piRoot) to the page number
1473 ** of the root page and returns SQLITE_OK. Otherwise, if an error occurs,
1474 ** an SQLite error code is returned and the final value of *piRoot
1475 ** undefined.
1476 */
recoverLostAndFoundFindRoot(sqlite3_recover * p,i64 iPg,i64 * piRoot)1477 static int recoverLostAndFoundFindRoot(
1478   sqlite3_recover *p,
1479   i64 iPg,
1480   i64 *piRoot
1481 ){
1482   RecoverStateLAF *pLaf = &p->laf;
1483 
1484   if( pLaf->pFindRoot==0 ){
1485     pLaf->pFindRoot = recoverPrepare(p, p->dbOut,
1486         "WITH RECURSIVE p(pgno) AS ("
1487         "  SELECT ?"
1488         "    UNION"
1489         "  SELECT parent FROM recovery.map AS m, p WHERE m.pgno=p.pgno"
1490         ") "
1491         "SELECT p.pgno FROM p, recovery.map m WHERE m.pgno=p.pgno "
1492         "    AND m.parent IS NULL"
1493     );
1494   }
1495   if( p->errCode==SQLITE_OK ){
1496     sqlite3_bind_int64(pLaf->pFindRoot, 1, iPg);
1497     if( sqlite3_step(pLaf->pFindRoot)==SQLITE_ROW ){
1498       *piRoot = sqlite3_column_int64(pLaf->pFindRoot, 0);
1499     }else{
1500       *piRoot = iPg;
1501     }
1502     recoverReset(p, pLaf->pFindRoot);
1503   }
1504   return p->errCode;
1505 }
1506 
1507 /*
1508 ** Recover data from page iPage of the input database and write it to
1509 ** the lost-and-found table in the output database.
1510 */
recoverLostAndFoundOnePage(sqlite3_recover * p,i64 iPage)1511 static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){
1512   RecoverStateLAF *pLaf = &p->laf;
1513   sqlite3_value **apVal = pLaf->apVal;
1514   sqlite3_stmt *pPageData = pLaf->pPageData;
1515   sqlite3_stmt *pInsert = pLaf->pInsert;
1516 
1517   int nVal = -1;
1518   int iPrevCell = 0;
1519   i64 iRoot = 0;
1520   int bHaveRowid = 0;
1521   i64 iRowid = 0;
1522   int ii = 0;
1523 
1524   if( recoverLostAndFoundFindRoot(p, iPage, &iRoot) ) return;
1525   sqlite3_bind_int64(pPageData, 1, iPage);
1526   while( p->errCode==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPageData) ){
1527     int iCell = sqlite3_column_int64(pPageData, 0);
1528     int iField = sqlite3_column_int64(pPageData, 1);
1529 
1530     if( iPrevCell!=iCell && nVal>=0 ){
1531       /* Insert the new row */
1532       sqlite3_bind_int64(pInsert, 1, iRoot);      /* rootpgno */
1533       sqlite3_bind_int64(pInsert, 2, iPage);      /* pgno */
1534       sqlite3_bind_int(pInsert, 3, nVal);         /* nfield */
1535       if( bHaveRowid ){
1536         sqlite3_bind_int64(pInsert, 4, iRowid);   /* id */
1537       }
1538       for(ii=0; ii<nVal; ii++){
1539         recoverBindValue(p, pInsert, 5+ii, apVal[ii]);
1540       }
1541       if( sqlite3_step(pInsert)==SQLITE_ROW ){
1542         recoverSqlCallback(p, (const char*)sqlite3_column_text(pInsert, 0));
1543       }
1544       recoverReset(p, pInsert);
1545 
1546       /* Discard the accumulated row data */
1547       for(ii=0; ii<nVal; ii++){
1548         sqlite3_value_free(apVal[ii]);
1549         apVal[ii] = 0;
1550       }
1551       sqlite3_clear_bindings(pInsert);
1552       bHaveRowid = 0;
1553       nVal = -1;
1554     }
1555 
1556     if( iCell<0 ) break;
1557 
1558     if( iField<0 ){
1559       assert( nVal==-1 );
1560       iRowid = sqlite3_column_int64(pPageData, 2);
1561       bHaveRowid = 1;
1562       nVal = 0;
1563     }else if( iField<pLaf->nMaxField ){
1564       sqlite3_value *pVal = sqlite3_column_value(pPageData, 2);
1565       apVal[iField] = sqlite3_value_dup(pVal);
1566       assert( iField==nVal || (nVal==-1 && iField==0) );
1567       nVal = iField+1;
1568       if( apVal[iField]==0 ){
1569         recoverError(p, SQLITE_NOMEM, 0);
1570       }
1571     }
1572 
1573     iPrevCell = iCell;
1574   }
1575   recoverReset(p, pPageData);
1576 
1577   for(ii=0; ii<nVal; ii++){
1578     sqlite3_value_free(apVal[ii]);
1579     apVal[ii] = 0;
1580   }
1581 }
1582 
1583 /*
1584 ** Perform one step (sqlite3_recover_step()) of work for the connection
1585 ** passed as the only argument, which is guaranteed to be in
1586 ** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found
1587 ** table of the output database is populated with recovered data that can
1588 ** not be assigned to any recovered schema object.
1589 */
recoverLostAndFound3Step(sqlite3_recover * p)1590 static int recoverLostAndFound3Step(sqlite3_recover *p){
1591   RecoverStateLAF *pLaf = &p->laf;
1592   if( p->errCode==SQLITE_OK ){
1593     if( pLaf->pInsert==0 ){
1594       return SQLITE_DONE;
1595     }else{
1596       if( p->errCode==SQLITE_OK ){
1597         int res = sqlite3_step(pLaf->pAllPage);
1598         if( res==SQLITE_ROW ){
1599           i64 iPage = sqlite3_column_int64(pLaf->pAllPage, 0);
1600           if( recoverBitmapQuery(pLaf->pUsed, iPage)==0 ){
1601             recoverLostAndFoundOnePage(p, iPage);
1602           }
1603         }else{
1604           recoverReset(p, pLaf->pAllPage);
1605           return SQLITE_DONE;
1606         }
1607       }
1608     }
1609   }
1610   return SQLITE_OK;
1611 }
1612 
1613 /*
1614 ** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3
1615 ** state - during which the lost-and-found table of the output database
1616 ** is populated with recovered data that can not be assigned to any
1617 ** recovered schema object.
1618 */
recoverLostAndFound3Init(sqlite3_recover * p)1619 static void recoverLostAndFound3Init(sqlite3_recover *p){
1620   RecoverStateLAF *pLaf = &p->laf;
1621 
1622   if( pLaf->nMaxField>0 ){
1623     char *zTab = 0;               /* Name of lost_and_found table */
1624 
1625     zTab = recoverLostAndFoundCreate(p, pLaf->nMaxField);
1626     pLaf->pInsert = recoverLostAndFoundInsert(p, zTab, pLaf->nMaxField);
1627     sqlite3_free(zTab);
1628 
1629     pLaf->pAllPage = recoverPreparePrintf(p, p->dbOut,
1630         "WITH RECURSIVE seq(ii) AS ("
1631         "  SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
1632         ")"
1633         "SELECT ii FROM seq" , p->laf.nPg
1634     );
1635     pLaf->pPageData = recoverPrepare(p, p->dbOut,
1636         "SELECT cell, field, value "
1637         "FROM sqlite_dbdata('getpage()') d WHERE d.pgno=? "
1638         "UNION ALL "
1639         "SELECT -1, -1, -1"
1640     );
1641 
1642     pLaf->apVal = (sqlite3_value**)recoverMalloc(p,
1643         pLaf->nMaxField*sizeof(sqlite3_value*)
1644     );
1645   }
1646 }
1647 
1648 /*
1649 ** Initialize resources required in RECOVER_STATE_WRITING state - during which
1650 ** tables recovered from the schema of the input database are populated with
1651 ** recovered data.
1652 */
recoverWriteDataInit(sqlite3_recover * p)1653 static int recoverWriteDataInit(sqlite3_recover *p){
1654   RecoverStateW1 *p1 = &p->w1;
1655   RecoverTable *pTbl = 0;
1656   int nByte = 0;
1657 
1658   /* Figure out the maximum number of columns for any table in the schema */
1659   assert( p1->nMax==0 );
1660   for(pTbl=p->pTblList; pTbl; pTbl=pTbl->pNext){
1661     if( pTbl->nCol>p1->nMax ) p1->nMax = pTbl->nCol;
1662   }
1663 
1664   /* Allocate an array of (sqlite3_value*) in which to accumulate the values
1665   ** that will be written to the output database in a single row. */
1666   nByte = sizeof(sqlite3_value*) * (p1->nMax+1);
1667   p1->apVal = (sqlite3_value**)recoverMalloc(p, nByte);
1668   if( p1->apVal==0 ) return p->errCode;
1669 
1670   /* Prepare the SELECT to loop through schema tables (pTbls) and the SELECT
1671   ** to loop through cells that appear to belong to a single table (pSel). */
1672   p1->pTbls = recoverPrepare(p, p->dbOut,
1673       "SELECT rootpage FROM recovery.schema "
1674       "  WHERE type='table' AND (sql NOT LIKE 'create virtual%')"
1675       "  ORDER BY (tbl_name='sqlite_sequence') ASC"
1676   );
1677   p1->pSel = recoverPrepare(p, p->dbOut,
1678       "WITH RECURSIVE pages(page) AS ("
1679       "  SELECT ?1"
1680       "    UNION"
1681       "  SELECT child FROM sqlite_dbptr('getpage()'), pages "
1682       "    WHERE pgno=page"
1683       ") "
1684       "SELECT page, cell, field, value "
1685       "FROM sqlite_dbdata('getpage()') d, pages p WHERE p.page=d.pgno "
1686       "UNION ALL "
1687       "SELECT 0, 0, 0, 0"
1688   );
1689 
1690   return p->errCode;
1691 }
1692 
1693 /*
1694 ** Clean up resources allocated by recoverWriteDataInit() (stuff in
1695 ** sqlite3_recover.w1).
1696 */
recoverWriteDataCleanup(sqlite3_recover * p)1697 static void recoverWriteDataCleanup(sqlite3_recover *p){
1698   RecoverStateW1 *p1 = &p->w1;
1699   int ii;
1700   for(ii=0; ii<p1->nVal; ii++){
1701     sqlite3_value_free(p1->apVal[ii]);
1702   }
1703   sqlite3_free(p1->apVal);
1704   recoverFinalize(p, p1->pInsert);
1705   recoverFinalize(p, p1->pTbls);
1706   recoverFinalize(p, p1->pSel);
1707   memset(p1, 0, sizeof(*p1));
1708 }
1709 
1710 /*
1711 ** Perform one step (sqlite3_recover_step()) of work for the connection
1712 ** passed as the only argument, which is guaranteed to be in
1713 ** RECOVER_STATE_WRITING state - during which tables recovered from the
1714 ** schema of the input database are populated with recovered data.
1715 */
recoverWriteDataStep(sqlite3_recover * p)1716 static int recoverWriteDataStep(sqlite3_recover *p){
1717   RecoverStateW1 *p1 = &p->w1;
1718   sqlite3_stmt *pSel = p1->pSel;
1719   sqlite3_value **apVal = p1->apVal;
1720 
1721   if( p->errCode==SQLITE_OK && p1->pTab==0 ){
1722     if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){
1723       i64 iRoot = sqlite3_column_int64(p1->pTbls, 0);
1724       p1->pTab = recoverFindTable(p, iRoot);
1725 
1726       recoverFinalize(p, p1->pInsert);
1727       p1->pInsert = 0;
1728 
1729       /* If this table is unknown, return early. The caller will invoke this
1730       ** function again and it will move on to the next table.  */
1731       if( p1->pTab==0 ) return p->errCode;
1732 
1733       /* If this is the sqlite_sequence table, delete any rows added by
1734       ** earlier INSERT statements on tables with AUTOINCREMENT primary
1735       ** keys before recovering its contents. The p1->pTbls SELECT statement
1736       ** is rigged to deliver "sqlite_sequence" last of all, so we don't
1737       ** worry about it being modified after it is recovered. */
1738       if( sqlite3_stricmp("sqlite_sequence", p1->pTab->zTab)==0 ){
1739         recoverExec(p, p->dbOut, "DELETE FROM sqlite_sequence");
1740         recoverSqlCallback(p, "DELETE FROM sqlite_sequence");
1741       }
1742 
1743       /* Bind the root page of this table within the original database to
1744       ** SELECT statement p1->pSel. The SELECT statement will then iterate
1745       ** through cells that look like they belong to table pTab.  */
1746       sqlite3_bind_int64(pSel, 1, iRoot);
1747 
1748       p1->nVal = 0;
1749       p1->bHaveRowid = 0;
1750       p1->iPrevPage = -1;
1751       p1->iPrevCell = -1;
1752     }else{
1753       return SQLITE_DONE;
1754     }
1755   }
1756   assert( p->errCode!=SQLITE_OK || p1->pTab );
1757 
1758   if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){
1759     RecoverTable *pTab = p1->pTab;
1760 
1761     i64 iPage = sqlite3_column_int64(pSel, 0);
1762     int iCell = sqlite3_column_int(pSel, 1);
1763     int iField = sqlite3_column_int(pSel, 2);
1764     sqlite3_value *pVal = sqlite3_column_value(pSel, 3);
1765     int bNewCell = (p1->iPrevPage!=iPage || p1->iPrevCell!=iCell);
1766 
1767     assert( bNewCell==0 || (iField==-1 || iField==0) );
1768     assert( bNewCell || iField==p1->nVal || p1->nVal==pTab->nCol );
1769 
1770     if( bNewCell ){
1771       int ii = 0;
1772       if( p1->nVal>=0 ){
1773         if( p1->pInsert==0 || p1->nVal!=p1->nInsert ){
1774           recoverFinalize(p, p1->pInsert);
1775           p1->pInsert = recoverInsertStmt(p, pTab, p1->nVal);
1776           p1->nInsert = p1->nVal;
1777         }
1778         if( p1->nVal>0 ){
1779           sqlite3_stmt *pInsert = p1->pInsert;
1780           for(ii=0; ii<pTab->nCol; ii++){
1781             RecoverColumn *pCol = &pTab->aCol[ii];
1782             int iBind = pCol->iBind;
1783             if( iBind>0 ){
1784               if( pCol->bIPK ){
1785                 sqlite3_bind_int64(pInsert, iBind, p1->iRowid);
1786               }else if( pCol->iField<p1->nVal ){
1787                 recoverBindValue(p, pInsert, iBind, apVal[pCol->iField]);
1788               }
1789             }
1790           }
1791           if( p->bRecoverRowid && pTab->iRowidBind>0 && p1->bHaveRowid ){
1792             sqlite3_bind_int64(pInsert, pTab->iRowidBind, p1->iRowid);
1793           }
1794           if( SQLITE_ROW==sqlite3_step(pInsert) ){
1795             const char *z = (const char*)sqlite3_column_text(pInsert, 0);
1796             recoverSqlCallback(p, z);
1797           }
1798           recoverReset(p, pInsert);
1799           assert( p->errCode || pInsert );
1800           if( pInsert ) sqlite3_clear_bindings(pInsert);
1801         }
1802       }
1803 
1804       for(ii=0; ii<p1->nVal; ii++){
1805         sqlite3_value_free(apVal[ii]);
1806         apVal[ii] = 0;
1807       }
1808       p1->nVal = -1;
1809       p1->bHaveRowid = 0;
1810     }
1811 
1812     if( iPage!=0 ){
1813       if( iField<0 ){
1814         p1->iRowid = sqlite3_column_int64(pSel, 3);
1815         assert( p1->nVal==-1 );
1816         p1->nVal = 0;
1817         p1->bHaveRowid = 1;
1818       }else if( iField<pTab->nCol ){
1819         assert( apVal[iField]==0 );
1820         apVal[iField] = sqlite3_value_dup( pVal );
1821         if( apVal[iField]==0 ){
1822           recoverError(p, SQLITE_NOMEM, 0);
1823         }
1824         p1->nVal = iField+1;
1825       }
1826       p1->iPrevCell = iCell;
1827       p1->iPrevPage = iPage;
1828     }
1829   }else{
1830     recoverReset(p, pSel);
1831     p1->pTab = 0;
1832   }
1833 
1834   return p->errCode;
1835 }
1836 
1837 /*
1838 ** Initialize resources required by sqlite3_recover_step() in
1839 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
1840 ** already allocated to a recovered schema element is determined.
1841 */
recoverLostAndFound1Init(sqlite3_recover * p)1842 static void recoverLostAndFound1Init(sqlite3_recover *p){
1843   RecoverStateLAF *pLaf = &p->laf;
1844   sqlite3_stmt *pStmt = 0;
1845 
1846   assert( p->laf.pUsed==0 );
1847   pLaf->nPg = recoverPageCount(p);
1848   pLaf->pUsed = recoverBitmapAlloc(p, pLaf->nPg);
1849 
1850   /* Prepare a statement to iterate through all pages that are part of any tree
1851   ** in the recoverable part of the input database schema to the bitmap. And,
1852   ** if !p->bFreelistCorrupt, add all pages that appear to be part of the
1853   ** freelist.  */
1854   pStmt = recoverPrepare(
1855       p, p->dbOut,
1856       "WITH trunk(pgno) AS ("
1857       "  SELECT read_i32(getpage(1), 8) AS x WHERE x>0"
1858       "    UNION"
1859       "  SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0"
1860       "),"
1861       "trunkdata(pgno, data) AS ("
1862       "  SELECT pgno, getpage(pgno) FROM trunk"
1863       "),"
1864       "freelist(data, n, freepgno) AS ("
1865       "  SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata"
1866       "    UNION ALL"
1867       "  SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0"
1868       "),"
1869       ""
1870       "roots(r) AS ("
1871       "  SELECT 1 UNION ALL"
1872       "  SELECT rootpage FROM recovery.schema WHERE rootpage>0"
1873       "),"
1874       "used(page) AS ("
1875       "  SELECT r FROM roots"
1876       "    UNION"
1877       "  SELECT child FROM sqlite_dbptr('getpage()'), used "
1878       "    WHERE pgno=page"
1879       ") "
1880       "SELECT page FROM used"
1881       " UNION ALL "
1882       "SELECT freepgno FROM freelist WHERE NOT ?"
1883   );
1884   if( pStmt ) sqlite3_bind_int(pStmt, 1, p->bFreelistCorrupt);
1885   pLaf->pUsedPages = pStmt;
1886 }
1887 
1888 /*
1889 ** Perform one step (sqlite3_recover_step()) of work for the connection
1890 ** passed as the only argument, which is guaranteed to be in
1891 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
1892 ** already allocated to a recovered schema element is determined.
1893 */
recoverLostAndFound1Step(sqlite3_recover * p)1894 static int recoverLostAndFound1Step(sqlite3_recover *p){
1895   RecoverStateLAF *pLaf = &p->laf;
1896   int rc = p->errCode;
1897   if( rc==SQLITE_OK ){
1898     rc = sqlite3_step(pLaf->pUsedPages);
1899     if( rc==SQLITE_ROW ){
1900       i64 iPg = sqlite3_column_int64(pLaf->pUsedPages, 0);
1901       recoverBitmapSet(pLaf->pUsed, iPg);
1902       rc = SQLITE_OK;
1903     }else{
1904       recoverFinalize(p, pLaf->pUsedPages);
1905       pLaf->pUsedPages = 0;
1906     }
1907   }
1908   return rc;
1909 }
1910 
1911 /*
1912 ** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2
1913 ** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1
1914 ** are sorted into sets that likely belonged to the same database tree.
1915 */
recoverLostAndFound2Init(sqlite3_recover * p)1916 static void recoverLostAndFound2Init(sqlite3_recover *p){
1917   RecoverStateLAF *pLaf = &p->laf;
1918 
1919   assert( p->laf.pAllAndParent==0 );
1920   assert( p->laf.pMapInsert==0 );
1921   assert( p->laf.pMaxField==0 );
1922   assert( p->laf.nMaxField==0 );
1923 
1924   pLaf->pMapInsert = recoverPrepare(p, p->dbOut,
1925       "INSERT OR IGNORE INTO recovery.map(pgno, parent) VALUES(?, ?)"
1926   );
1927   pLaf->pAllAndParent = recoverPreparePrintf(p, p->dbOut,
1928       "WITH RECURSIVE seq(ii) AS ("
1929       "  SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
1930       ")"
1931       "SELECT pgno, child FROM sqlite_dbptr('getpage()') "
1932       " UNION ALL "
1933       "SELECT NULL, ii FROM seq", p->laf.nPg
1934   );
1935   pLaf->pMaxField = recoverPreparePrintf(p, p->dbOut,
1936       "SELECT max(field)+1 FROM sqlite_dbdata('getpage') WHERE pgno = ?"
1937   );
1938 }
1939 
1940 /*
1941 ** Perform one step (sqlite3_recover_step()) of work for the connection
1942 ** passed as the only argument, which is guaranteed to be in
1943 ** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified
1944 ** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged
1945 ** to the same database tree.
1946 */
recoverLostAndFound2Step(sqlite3_recover * p)1947 static int recoverLostAndFound2Step(sqlite3_recover *p){
1948   RecoverStateLAF *pLaf = &p->laf;
1949   if( p->errCode==SQLITE_OK ){
1950     int res = sqlite3_step(pLaf->pAllAndParent);
1951     if( res==SQLITE_ROW ){
1952       i64 iChild = sqlite3_column_int(pLaf->pAllAndParent, 1);
1953       if( recoverBitmapQuery(pLaf->pUsed, iChild)==0 ){
1954         sqlite3_bind_int64(pLaf->pMapInsert, 1, iChild);
1955         sqlite3_bind_value(pLaf->pMapInsert, 2,
1956             sqlite3_column_value(pLaf->pAllAndParent, 0)
1957         );
1958         sqlite3_step(pLaf->pMapInsert);
1959         recoverReset(p, pLaf->pMapInsert);
1960         sqlite3_bind_int64(pLaf->pMaxField, 1, iChild);
1961         if( SQLITE_ROW==sqlite3_step(pLaf->pMaxField) ){
1962           int nMax = sqlite3_column_int(pLaf->pMaxField, 0);
1963           if( nMax>pLaf->nMaxField ) pLaf->nMaxField = nMax;
1964         }
1965         recoverReset(p, pLaf->pMaxField);
1966       }
1967     }else{
1968       recoverFinalize(p, pLaf->pAllAndParent);
1969       pLaf->pAllAndParent =0;
1970       return SQLITE_DONE;
1971     }
1972   }
1973   return p->errCode;
1974 }
1975 
1976 /*
1977 ** Free all resources allocated as part of sqlite3_recover_step() calls
1978 ** in one of the RECOVER_STATE_LOSTANDFOUND[123] states.
1979 */
recoverLostAndFoundCleanup(sqlite3_recover * p)1980 static void recoverLostAndFoundCleanup(sqlite3_recover *p){
1981   recoverBitmapFree(p->laf.pUsed);
1982   p->laf.pUsed = 0;
1983   sqlite3_finalize(p->laf.pUsedPages);
1984   sqlite3_finalize(p->laf.pAllAndParent);
1985   sqlite3_finalize(p->laf.pMapInsert);
1986   sqlite3_finalize(p->laf.pMaxField);
1987   sqlite3_finalize(p->laf.pFindRoot);
1988   sqlite3_finalize(p->laf.pInsert);
1989   sqlite3_finalize(p->laf.pAllPage);
1990   sqlite3_finalize(p->laf.pPageData);
1991   p->laf.pUsedPages = 0;
1992   p->laf.pAllAndParent = 0;
1993   p->laf.pMapInsert = 0;
1994   p->laf.pMaxField = 0;
1995   p->laf.pFindRoot = 0;
1996   p->laf.pInsert = 0;
1997   p->laf.pAllPage = 0;
1998   p->laf.pPageData = 0;
1999   sqlite3_free(p->laf.apVal);
2000   p->laf.apVal = 0;
2001 }
2002 
2003 /*
2004 ** Free all resources allocated as part of sqlite3_recover_step() calls.
2005 */
recoverFinalCleanup(sqlite3_recover * p)2006 static void recoverFinalCleanup(sqlite3_recover *p){
2007   RecoverTable *pTab = 0;
2008   RecoverTable *pNext = 0;
2009 
2010   recoverWriteDataCleanup(p);
2011   recoverLostAndFoundCleanup(p);
2012 
2013   for(pTab=p->pTblList; pTab; pTab=pNext){
2014     pNext = pTab->pNext;
2015     sqlite3_free(pTab);
2016   }
2017   p->pTblList = 0;
2018   sqlite3_finalize(p->pGetPage);
2019   p->pGetPage = 0;
2020 
2021   {
2022 #ifndef NDEBUG
2023     int res =
2024 #endif
2025        sqlite3_close(p->dbOut);
2026     assert( res==SQLITE_OK );
2027   }
2028   p->dbOut = 0;
2029 }
2030 
2031 /*
2032 ** Decode and return an unsigned 16-bit big-endian integer value from
2033 ** buffer a[].
2034 */
recoverGetU16(const u8 * a)2035 static u32 recoverGetU16(const u8 *a){
2036   return (((u32)a[0])<<8) + ((u32)a[1]);
2037 }
2038 
2039 /*
2040 ** Decode and return an unsigned 32-bit big-endian integer value from
2041 ** buffer a[].
2042 */
recoverGetU32(const u8 * a)2043 static u32 recoverGetU32(const u8 *a){
2044   return (((u32)a[0])<<24) + (((u32)a[1])<<16) + (((u32)a[2])<<8) + ((u32)a[3]);
2045 }
2046 
2047 /*
2048 ** Decode an SQLite varint from buffer a[]. Write the decoded value to (*pVal)
2049 ** and return the number of bytes consumed.
2050 */
recoverGetVarint(const u8 * a,i64 * pVal)2051 static int recoverGetVarint(const u8 *a, i64 *pVal){
2052   sqlite3_uint64 u = 0;
2053   int i;
2054   for(i=0; i<8; i++){
2055     u = (u<<7) + (a[i]&0x7f);
2056     if( (a[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; }
2057   }
2058   u = (u<<8) + (a[i]&0xff);
2059   *pVal = (sqlite3_int64)u;
2060   return 9;
2061 }
2062 
2063 /*
2064 ** The second argument points to a buffer n bytes in size. If this buffer
2065 ** or a prefix thereof appears to contain a well-formed SQLite b-tree page,
2066 ** return the page-size in bytes. Otherwise, if the buffer does not
2067 ** appear to contain a well-formed b-tree page, return 0.
2068 */
recoverIsValidPage(u8 * aTmp,const u8 * a,int n)2069 static int recoverIsValidPage(u8 *aTmp, const u8 *a, int n){
2070   u8 *aUsed = aTmp;
2071   int nFrag = 0;
2072   int nActual = 0;
2073   int iFree = 0;
2074   int nCell = 0;                  /* Number of cells on page */
2075   int iCellOff = 0;               /* Offset of cell array in page */
2076   int iContent = 0;
2077   int eType = 0;
2078   int ii = 0;
2079 
2080   eType = (int)a[0];
2081   if( eType!=0x02 && eType!=0x05 && eType!=0x0A && eType!=0x0D ) return 0;
2082 
2083   iFree = (int)recoverGetU16(&a[1]);
2084   nCell = (int)recoverGetU16(&a[3]);
2085   iContent = (int)recoverGetU16(&a[5]);
2086   if( iContent==0 ) iContent = 65536;
2087   nFrag = (int)a[7];
2088 
2089   if( iContent>n ) return 0;
2090 
2091   memset(aUsed, 0, n);
2092   memset(aUsed, 0xFF, iContent);
2093 
2094   /* Follow the free-list. This is the same format for all b-tree pages. */
2095   if( iFree && iFree<=iContent ) return 0;
2096   while( iFree ){
2097     int iNext = 0;
2098     int nByte = 0;
2099     if( iFree>(n-4) ) return 0;
2100     iNext = recoverGetU16(&a[iFree]);
2101     nByte = recoverGetU16(&a[iFree+2]);
2102     if( iFree+nByte>n ) return 0;
2103     if( iNext && iNext<iFree+nByte ) return 0;
2104     memset(&aUsed[iFree], 0xFF, nByte);
2105     iFree = iNext;
2106   }
2107 
2108   /* Run through the cells */
2109   if( eType==0x02 || eType==0x05 ){
2110     iCellOff = 12;
2111   }else{
2112     iCellOff = 8;
2113   }
2114   if( (iCellOff + 2*nCell)>iContent ) return 0;
2115   for(ii=0; ii<nCell; ii++){
2116     int iByte;
2117     i64 nPayload = 0;
2118     int nByte = 0;
2119     int iOff = recoverGetU16(&a[iCellOff + 2*ii]);
2120     if( iOff<iContent || iOff>n ){
2121       return 0;
2122     }
2123     if( eType==0x05 || eType==0x02 ) nByte += 4;
2124     nByte += recoverGetVarint(&a[iOff+nByte], &nPayload);
2125     if( eType==0x0D ){
2126       i64 dummy = 0;
2127       nByte += recoverGetVarint(&a[iOff+nByte], &dummy);
2128     }
2129     if( eType!=0x05 ){
2130       int X = (eType==0x0D) ? n-35 : (((n-12)*64/255)-23);
2131       int M = ((n-12)*32/255)-23;
2132       int K = M+((nPayload-M)%(n-4));
2133 
2134       if( nPayload<X ){
2135         nByte += nPayload;
2136       }else if( K<=X ){
2137         nByte += K+4;
2138       }else{
2139         nByte += M+4;
2140       }
2141     }
2142 
2143     if( iOff+nByte>n ){
2144       return 0;
2145     }
2146     for(iByte=iOff; iByte<(iOff+nByte); iByte++){
2147       if( aUsed[iByte]!=0 ){
2148         return 0;
2149       }
2150       aUsed[iByte] = 0xFF;
2151     }
2152   }
2153 
2154   nActual = 0;
2155   for(ii=0; ii<n; ii++){
2156     if( aUsed[ii]==0 ) nActual++;
2157   }
2158   return (nActual==nFrag);
2159 }
2160 
2161 
2162 static int recoverVfsClose(sqlite3_file*);
2163 static int recoverVfsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
2164 static int recoverVfsWrite(sqlite3_file*, const void*, int, sqlite3_int64);
2165 static int recoverVfsTruncate(sqlite3_file*, sqlite3_int64 size);
2166 static int recoverVfsSync(sqlite3_file*, int flags);
2167 static int recoverVfsFileSize(sqlite3_file*, sqlite3_int64 *pSize);
2168 static int recoverVfsLock(sqlite3_file*, int);
2169 static int recoverVfsUnlock(sqlite3_file*, int);
2170 static int recoverVfsCheckReservedLock(sqlite3_file*, int *pResOut);
2171 static int recoverVfsFileControl(sqlite3_file*, int op, void *pArg);
2172 static int recoverVfsSectorSize(sqlite3_file*);
2173 static int recoverVfsDeviceCharacteristics(sqlite3_file*);
2174 static int recoverVfsShmMap(sqlite3_file*, int, int, int, void volatile**);
2175 static int recoverVfsShmLock(sqlite3_file*, int offset, int n, int flags);
2176 static void recoverVfsShmBarrier(sqlite3_file*);
2177 static int recoverVfsShmUnmap(sqlite3_file*, int deleteFlag);
2178 static int recoverVfsFetch(sqlite3_file*, sqlite3_int64, int, void**);
2179 static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p);
2180 
2181 static sqlite3_io_methods recover_methods = {
2182   2, /* iVersion */
2183   recoverVfsClose,
2184   recoverVfsRead,
2185   recoverVfsWrite,
2186   recoverVfsTruncate,
2187   recoverVfsSync,
2188   recoverVfsFileSize,
2189   recoverVfsLock,
2190   recoverVfsUnlock,
2191   recoverVfsCheckReservedLock,
2192   recoverVfsFileControl,
2193   recoverVfsSectorSize,
2194   recoverVfsDeviceCharacteristics,
2195   recoverVfsShmMap,
2196   recoverVfsShmLock,
2197   recoverVfsShmBarrier,
2198   recoverVfsShmUnmap,
2199   recoverVfsFetch,
2200   recoverVfsUnfetch
2201 };
2202 
recoverVfsClose(sqlite3_file * pFd)2203 static int recoverVfsClose(sqlite3_file *pFd){
2204   assert( pFd->pMethods!=&recover_methods );
2205   return pFd->pMethods->xClose(pFd);
2206 }
2207 
2208 /*
2209 ** Write value v to buffer a[] as a 16-bit big-endian unsigned integer.
2210 */
recoverPutU16(u8 * a,u32 v)2211 static void recoverPutU16(u8 *a, u32 v){
2212   a[0] = (v>>8) & 0x00FF;
2213   a[1] = (v>>0) & 0x00FF;
2214 }
2215 
2216 /*
2217 ** Write value v to buffer a[] as a 32-bit big-endian unsigned integer.
2218 */
recoverPutU32(u8 * a,u32 v)2219 static void recoverPutU32(u8 *a, u32 v){
2220   a[0] = (v>>24) & 0x00FF;
2221   a[1] = (v>>16) & 0x00FF;
2222   a[2] = (v>>8) & 0x00FF;
2223   a[3] = (v>>0) & 0x00FF;
2224 }
2225 
2226 /*
2227 ** Detect the page-size of the database opened by file-handle pFd by
2228 ** searching the first part of the file for a well-formed SQLite b-tree
2229 ** page. If parameter nReserve is non-zero, then as well as searching for
2230 ** a b-tree page with zero reserved bytes, this function searches for one
2231 ** with nReserve reserved bytes at the end of it.
2232 **
2233 ** If successful, set variable p->detected_pgsz to the detected page-size
2234 ** in bytes and return SQLITE_OK. Or, if no error occurs but no valid page
2235 ** can be found, return SQLITE_OK but leave p->detected_pgsz set to 0. Or,
2236 ** if an error occurs (e.g. an IO or OOM error), then an SQLite error code
2237 ** is returned. The final value of p->detected_pgsz is undefined in this
2238 ** case.
2239 */
recoverVfsDetectPagesize(sqlite3_recover * p,sqlite3_file * pFd,u32 nReserve,i64 nSz)2240 static int recoverVfsDetectPagesize(
2241   sqlite3_recover *p,             /* Recover handle */
2242   sqlite3_file *pFd,              /* File-handle open on input database */
2243   u32 nReserve,                   /* Possible nReserve value */
2244   i64 nSz                         /* Size of database file in bytes */
2245 ){
2246   int rc = SQLITE_OK;
2247   const int nMin = 512;
2248   const int nMax = 65536;
2249   const int nMaxBlk = 4;
2250   u32 pgsz = 0;
2251   int iBlk = 0;
2252   u8 *aPg = 0;
2253   u8 *aTmp = 0;
2254   int nBlk = 0;
2255 
2256   aPg = (u8*)sqlite3_malloc(2*nMax);
2257   if( aPg==0 ) return SQLITE_NOMEM;
2258   aTmp = &aPg[nMax];
2259 
2260   nBlk = (nSz+nMax-1)/nMax;
2261   if( nBlk>nMaxBlk ) nBlk = nMaxBlk;
2262 
2263   do {
2264     for(iBlk=0; rc==SQLITE_OK && iBlk<nBlk; iBlk++){
2265       int nByte = (nSz>=((iBlk+1)*nMax)) ? nMax : (nSz % nMax);
2266       memset(aPg, 0, nMax);
2267       rc = pFd->pMethods->xRead(pFd, aPg, nByte, iBlk*nMax);
2268       if( rc==SQLITE_OK ){
2269         int pgsz2;
2270         for(pgsz2=(pgsz ? pgsz*2 : nMin); pgsz2<=nMax; pgsz2=pgsz2*2){
2271           int iOff;
2272           for(iOff=0; iOff<nMax; iOff+=pgsz2){
2273             if( recoverIsValidPage(aTmp, &aPg[iOff], pgsz2-nReserve) ){
2274               pgsz = pgsz2;
2275               break;
2276             }
2277           }
2278         }
2279       }
2280     }
2281     if( pgsz>(u32)p->detected_pgsz ){
2282       p->detected_pgsz = pgsz;
2283       p->nReserve = nReserve;
2284     }
2285     if( nReserve==0 ) break;
2286     nReserve = 0;
2287   }while( 1 );
2288 
2289   p->detected_pgsz = pgsz;
2290   sqlite3_free(aPg);
2291   return rc;
2292 }
2293 
2294 /*
2295 ** The xRead() method of the wrapper VFS. This is used to intercept calls
2296 ** to read page 1 of the input database.
2297 */
recoverVfsRead(sqlite3_file * pFd,void * aBuf,int nByte,i64 iOff)2298 static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){
2299   int rc = SQLITE_OK;
2300   if( pFd->pMethods==&recover_methods ){
2301     pFd->pMethods = recover_g.pMethods;
2302     rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff);
2303     if( nByte==16 ){
2304       sqlite3_randomness(16, aBuf);
2305     }else
2306     if( rc==SQLITE_OK && iOff==0 && nByte>=108 ){
2307       /* Ensure that the database has a valid header file. The only fields
2308       ** that really matter to recovery are:
2309       **
2310       **   + Database page size (16-bits at offset 16)
2311       **   + Size of db in pages (32-bits at offset 28)
2312       **   + Database encoding (32-bits at offset 56)
2313       **
2314       ** Also preserved are:
2315       **
2316       **   + first freelist page (32-bits at offset 32)
2317       **   + size of freelist (32-bits at offset 36)
2318       **
2319       ** We also try to preserve the auto-vacuum, incr-value, user-version
2320       ** and application-id fields - all 32 bit quantities at offsets
2321       ** 52, 60, 64 and 68. All other fields are set to known good values.
2322       **
2323       ** Byte offset 105 should also contain the page-size as a 16-bit
2324       ** integer.
2325       */
2326       const int aPreserve[] = {32, 36, 52, 60, 64, 68};
2327       u8 aHdr[108] = {
2328         0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
2329         0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00,
2330         0xFF, 0xFF, 0x01, 0x01, 0x00, 0x40, 0x20, 0x20,
2331         0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
2332         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2333         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
2334         0x00, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
2335         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2336         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2337         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2339         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340         0x00, 0x2e, 0x5b, 0x30,
2341 
2342         0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00
2343       };
2344       u8 *a = (u8*)aBuf;
2345 
2346       u32 pgsz = recoverGetU16(&a[16]);
2347       u32 nReserve = a[20];
2348       u32 enc = recoverGetU32(&a[56]);
2349       u32 dbsz = 0;
2350       i64 dbFileSize = 0;
2351       int ii;
2352       sqlite3_recover *p = recover_g.p;
2353 
2354       if( pgsz==0x01 ) pgsz = 65536;
2355       rc = pFd->pMethods->xFileSize(pFd, &dbFileSize);
2356 
2357       if( rc==SQLITE_OK && p->detected_pgsz==0 ){
2358         rc = recoverVfsDetectPagesize(p, pFd, nReserve, dbFileSize);
2359       }
2360       if( p->detected_pgsz ){
2361         pgsz = p->detected_pgsz;
2362         nReserve = p->nReserve;
2363       }
2364 
2365       if( pgsz ){
2366         dbsz = dbFileSize / pgsz;
2367       }
2368       if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16BE && enc!=SQLITE_UTF16LE ){
2369         enc = SQLITE_UTF8;
2370       }
2371 
2372       sqlite3_free(p->pPage1Cache);
2373       p->pPage1Cache = 0;
2374       p->pPage1Disk = 0;
2375 
2376       p->pgsz = nByte;
2377       p->pPage1Cache = (u8*)recoverMalloc(p, nByte*2);
2378       if( p->pPage1Cache ){
2379         p->pPage1Disk = &p->pPage1Cache[nByte];
2380         memcpy(p->pPage1Disk, aBuf, nByte);
2381 
2382         recoverPutU32(&aHdr[28], dbsz);
2383         recoverPutU32(&aHdr[56], enc);
2384         recoverPutU16(&aHdr[105], pgsz-nReserve);
2385         if( pgsz==65536 ) pgsz = 1;
2386         recoverPutU16(&aHdr[16], pgsz);
2387         aHdr[20] = nReserve;
2388         for(ii=0; ii<sizeof(aPreserve)/sizeof(aPreserve[0]); ii++){
2389           memcpy(&aHdr[aPreserve[ii]], &a[aPreserve[ii]], 4);
2390         }
2391         memcpy(aBuf, aHdr, sizeof(aHdr));
2392         memset(&((u8*)aBuf)[sizeof(aHdr)], 0, nByte-sizeof(aHdr));
2393 
2394         memcpy(p->pPage1Cache, aBuf, nByte);
2395       }else{
2396         rc = p->errCode;
2397       }
2398 
2399     }
2400     pFd->pMethods = &recover_methods;
2401   }else{
2402     rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff);
2403   }
2404   return rc;
2405 }
2406 
2407 /*
2408 ** Used to make sqlite3_io_methods wrapper methods less verbose.
2409 */
2410 #define RECOVER_VFS_WRAPPER(code)                         \
2411   int rc = SQLITE_OK;                                     \
2412   if( pFd->pMethods==&recover_methods ){                  \
2413     pFd->pMethods = recover_g.pMethods;                   \
2414     rc = code;                                            \
2415     pFd->pMethods = &recover_methods;                     \
2416   }else{                                                  \
2417     rc = code;                                            \
2418   }                                                       \
2419   return rc;
2420 
2421 /*
2422 ** Methods of the wrapper VFS. All methods except for xRead() and xClose()
2423 ** simply uninstall the sqlite3_io_methods wrapper, invoke the equivalent
2424 ** method on the lower level VFS, then reinstall the wrapper before returning.
2425 ** Those that return an integer value use the RECOVER_VFS_WRAPPER macro.
2426 */
recoverVfsWrite(sqlite3_file * pFd,const void * aBuf,int nByte,i64 iOff)2427 static int recoverVfsWrite(
2428   sqlite3_file *pFd, const void *aBuf, int nByte, i64 iOff
2429 ){
2430   RECOVER_VFS_WRAPPER (
2431       pFd->pMethods->xWrite(pFd, aBuf, nByte, iOff)
2432   );
2433 }
recoverVfsTruncate(sqlite3_file * pFd,sqlite3_int64 size)2434 static int recoverVfsTruncate(sqlite3_file *pFd, sqlite3_int64 size){
2435   RECOVER_VFS_WRAPPER (
2436       pFd->pMethods->xTruncate(pFd, size)
2437   );
2438 }
recoverVfsSync(sqlite3_file * pFd,int flags)2439 static int recoverVfsSync(sqlite3_file *pFd, int flags){
2440   RECOVER_VFS_WRAPPER (
2441       pFd->pMethods->xSync(pFd, flags)
2442   );
2443 }
recoverVfsFileSize(sqlite3_file * pFd,sqlite3_int64 * pSize)2444 static int recoverVfsFileSize(sqlite3_file *pFd, sqlite3_int64 *pSize){
2445   RECOVER_VFS_WRAPPER (
2446       pFd->pMethods->xFileSize(pFd, pSize)
2447   );
2448 }
recoverVfsLock(sqlite3_file * pFd,int eLock)2449 static int recoverVfsLock(sqlite3_file *pFd, int eLock){
2450   RECOVER_VFS_WRAPPER (
2451       pFd->pMethods->xLock(pFd, eLock)
2452   );
2453 }
recoverVfsUnlock(sqlite3_file * pFd,int eLock)2454 static int recoverVfsUnlock(sqlite3_file *pFd, int eLock){
2455   RECOVER_VFS_WRAPPER (
2456       pFd->pMethods->xUnlock(pFd, eLock)
2457   );
2458 }
recoverVfsCheckReservedLock(sqlite3_file * pFd,int * pResOut)2459 static int recoverVfsCheckReservedLock(sqlite3_file *pFd, int *pResOut){
2460   RECOVER_VFS_WRAPPER (
2461       pFd->pMethods->xCheckReservedLock(pFd, pResOut)
2462   );
2463 }
recoverVfsFileControl(sqlite3_file * pFd,int op,void * pArg)2464 static int recoverVfsFileControl(sqlite3_file *pFd, int op, void *pArg){
2465   RECOVER_VFS_WRAPPER (
2466     (pFd->pMethods ?  pFd->pMethods->xFileControl(pFd, op, pArg) : SQLITE_NOTFOUND)
2467   );
2468 }
recoverVfsSectorSize(sqlite3_file * pFd)2469 static int recoverVfsSectorSize(sqlite3_file *pFd){
2470   RECOVER_VFS_WRAPPER (
2471       pFd->pMethods->xSectorSize(pFd)
2472   );
2473 }
recoverVfsDeviceCharacteristics(sqlite3_file * pFd)2474 static int recoverVfsDeviceCharacteristics(sqlite3_file *pFd){
2475   RECOVER_VFS_WRAPPER (
2476       pFd->pMethods->xDeviceCharacteristics(pFd)
2477   );
2478 }
recoverVfsShmMap(sqlite3_file * pFd,int iPg,int pgsz,int bExtend,void volatile ** pp)2479 static int recoverVfsShmMap(
2480   sqlite3_file *pFd, int iPg, int pgsz, int bExtend, void volatile **pp
2481 ){
2482   RECOVER_VFS_WRAPPER (
2483       pFd->pMethods->xShmMap(pFd, iPg, pgsz, bExtend, pp)
2484   );
2485 }
recoverVfsShmLock(sqlite3_file * pFd,int offset,int n,int flags)2486 static int recoverVfsShmLock(sqlite3_file *pFd, int offset, int n, int flags){
2487   RECOVER_VFS_WRAPPER (
2488       pFd->pMethods->xShmLock(pFd, offset, n, flags)
2489   );
2490 }
recoverVfsShmBarrier(sqlite3_file * pFd)2491 static void recoverVfsShmBarrier(sqlite3_file *pFd){
2492   if( pFd->pMethods==&recover_methods ){
2493     pFd->pMethods = recover_g.pMethods;
2494     pFd->pMethods->xShmBarrier(pFd);
2495     pFd->pMethods = &recover_methods;
2496   }else{
2497     pFd->pMethods->xShmBarrier(pFd);
2498   }
2499 }
recoverVfsShmUnmap(sqlite3_file * pFd,int deleteFlag)2500 static int recoverVfsShmUnmap(sqlite3_file *pFd, int deleteFlag){
2501   RECOVER_VFS_WRAPPER (
2502       pFd->pMethods->xShmUnmap(pFd, deleteFlag)
2503   );
2504 }
2505 
recoverVfsFetch(sqlite3_file * pFd,sqlite3_int64 iOff,int iAmt,void ** pp)2506 static int recoverVfsFetch(
2507   sqlite3_file *pFd,
2508   sqlite3_int64 iOff,
2509   int iAmt,
2510   void **pp
2511 ){
2512   *pp = 0;
2513   return SQLITE_OK;
2514 }
recoverVfsUnfetch(sqlite3_file * pFd,sqlite3_int64 iOff,void * p)2515 static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p){
2516   return SQLITE_OK;
2517 }
2518 
2519 /*
2520 ** Install the VFS wrapper around the file-descriptor open on the input
2521 ** database for recover handle p. Mutex RECOVER_MUTEX_ID must be held
2522 ** when this function is called.
2523 */
recoverInstallWrapper(sqlite3_recover * p)2524 static void recoverInstallWrapper(sqlite3_recover *p){
2525   sqlite3_file *pFd = 0;
2526   assert( recover_g.pMethods==0 );
2527   recoverAssertMutexHeld();
2528   sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
2529   assert( pFd==0 || pFd->pMethods!=&recover_methods );
2530   if( pFd && pFd->pMethods ){
2531     int iVersion = 1 + (pFd->pMethods->iVersion>1 && pFd->pMethods->xShmMap!=0);
2532     recover_g.pMethods = pFd->pMethods;
2533     recover_g.p = p;
2534     recover_methods.iVersion = iVersion;
2535     pFd->pMethods = &recover_methods;
2536   }
2537 }
2538 
2539 /*
2540 ** Uninstall the VFS wrapper that was installed around the file-descriptor open
2541 ** on the input database for recover handle p. Mutex RECOVER_MUTEX_ID must be
2542 ** held when this function is called.
2543 */
recoverUninstallWrapper(sqlite3_recover * p)2544 static void recoverUninstallWrapper(sqlite3_recover *p){
2545   sqlite3_file *pFd = 0;
2546   recoverAssertMutexHeld();
2547   sqlite3_file_control(p->dbIn, p->zDb,SQLITE_FCNTL_FILE_POINTER,(void*)&pFd);
2548   if( pFd && pFd->pMethods ){
2549     pFd->pMethods = recover_g.pMethods;
2550     recover_g.pMethods = 0;
2551     recover_g.p = 0;
2552   }
2553 }
2554 
2555 /*
2556 ** This function does the work of a single sqlite3_recover_step() call. It
2557 ** is guaranteed that the handle is not in an error state when this
2558 ** function is called.
2559 */
recoverStep(sqlite3_recover * p)2560 static void recoverStep(sqlite3_recover *p){
2561   assert( p && p->errCode==SQLITE_OK );
2562   switch( p->eState ){
2563     case RECOVER_STATE_INIT:
2564       /* This is the very first call to sqlite3_recover_step() on this object.
2565       */
2566       recoverSqlCallback(p, "BEGIN");
2567       recoverSqlCallback(p, "PRAGMA writable_schema = on");
2568 
2569       recoverEnterMutex();
2570       recoverInstallWrapper(p);
2571 
2572       /* Open the output database. And register required virtual tables and
2573       ** user functions with the new handle. */
2574       recoverOpenOutput(p);
2575 
2576       /* Open transactions on both the input and output databases. */
2577       recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
2578       recoverExec(p, p->dbIn, "BEGIN");
2579       if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
2580       recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema");
2581       recoverTransferSettings(p);
2582       recoverOpenRecovery(p);
2583       recoverCacheSchema(p);
2584 
2585       recoverUninstallWrapper(p);
2586       recoverLeaveMutex();
2587 
2588       recoverExec(p, p->dbOut, "BEGIN");
2589 
2590       recoverWriteSchema1(p);
2591       p->eState = RECOVER_STATE_WRITING;
2592       break;
2593 
2594     case RECOVER_STATE_WRITING: {
2595       if( p->w1.pTbls==0 ){
2596         recoverWriteDataInit(p);
2597       }
2598       if( SQLITE_DONE==recoverWriteDataStep(p) ){
2599         recoverWriteDataCleanup(p);
2600         if( p->zLostAndFound ){
2601           p->eState = RECOVER_STATE_LOSTANDFOUND1;
2602         }else{
2603           p->eState = RECOVER_STATE_SCHEMA2;
2604         }
2605       }
2606       break;
2607     }
2608 
2609     case RECOVER_STATE_LOSTANDFOUND1: {
2610       if( p->laf.pUsed==0 ){
2611         recoverLostAndFound1Init(p);
2612       }
2613       if( SQLITE_DONE==recoverLostAndFound1Step(p) ){
2614         p->eState = RECOVER_STATE_LOSTANDFOUND2;
2615       }
2616       break;
2617     }
2618     case RECOVER_STATE_LOSTANDFOUND2: {
2619       if( p->laf.pAllAndParent==0 ){
2620         recoverLostAndFound2Init(p);
2621       }
2622       if( SQLITE_DONE==recoverLostAndFound2Step(p) ){
2623         p->eState = RECOVER_STATE_LOSTANDFOUND3;
2624       }
2625       break;
2626     }
2627 
2628     case RECOVER_STATE_LOSTANDFOUND3: {
2629       if( p->laf.pInsert==0 ){
2630         recoverLostAndFound3Init(p);
2631       }
2632       if( SQLITE_DONE==recoverLostAndFound3Step(p) ){
2633         p->eState = RECOVER_STATE_SCHEMA2;
2634       }
2635       break;
2636     }
2637 
2638     case RECOVER_STATE_SCHEMA2: {
2639       int rc = SQLITE_OK;
2640 
2641       recoverWriteSchema2(p);
2642       p->eState = RECOVER_STATE_DONE;
2643 
2644       /* If no error has occurred, commit the write transaction on the output
2645       ** database. Regardless of whether or not an error has occurred, make
2646       ** an attempt to end the read transaction on the input database.  */
2647       recoverExec(p, p->dbOut, "COMMIT");
2648       rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
2649       if( p->errCode==SQLITE_OK ) p->errCode = rc;
2650 
2651       recoverSqlCallback(p, "PRAGMA writable_schema = off");
2652       recoverSqlCallback(p, "COMMIT");
2653       p->eState = RECOVER_STATE_DONE;
2654       recoverFinalCleanup(p);
2655       break;
2656     };
2657 
2658     case RECOVER_STATE_DONE: {
2659       /* no-op */
2660       break;
2661     };
2662   }
2663 }
2664 
2665 
2666 /*
2667 ** This is a worker function that does the heavy lifting for both init
2668 ** functions:
2669 **
2670 **     sqlite3_recover_init()
2671 **     sqlite3_recover_init_sql()
2672 **
2673 ** All this function does is allocate space for the recover handle and
2674 ** take copies of the input parameters. All the real work is done within
2675 ** sqlite3_recover_run().
2676 */
recoverInit(sqlite3 * db,const char * zDb,const char * zUri,int (* xSql)(void *,const char *),void * pSqlCtx)2677 sqlite3_recover *recoverInit(
2678   sqlite3* db,
2679   const char *zDb,
2680   const char *zUri,               /* Output URI for _recover_init() */
2681   int (*xSql)(void*, const char*),/* SQL callback for _recover_init_sql() */
2682   void *pSqlCtx                   /* Context arg for _recover_init_sql() */
2683 ){
2684   sqlite3_recover *pRet = 0;
2685   int nDb = 0;
2686   int nUri = 0;
2687   int nByte = 0;
2688 
2689   if( zDb==0 ){ zDb = "main"; }
2690 
2691   nDb = recoverStrlen(zDb);
2692   nUri = recoverStrlen(zUri);
2693 
2694   nByte = sizeof(sqlite3_recover) + nDb+1 + nUri+1;
2695   pRet = (sqlite3_recover*)sqlite3_malloc(nByte);
2696   if( pRet ){
2697     memset(pRet, 0, nByte);
2698     pRet->dbIn = db;
2699     pRet->zDb = (char*)&pRet[1];
2700     pRet->zUri = &pRet->zDb[nDb+1];
2701     memcpy(pRet->zDb, zDb, nDb);
2702     if( nUri>0 && zUri ) memcpy(pRet->zUri, zUri, nUri);
2703     pRet->xSql = xSql;
2704     pRet->pSqlCtx = pSqlCtx;
2705     pRet->bRecoverRowid = RECOVER_ROWID_DEFAULT;
2706   }
2707 
2708   return pRet;
2709 }
2710 
2711 /*
2712 ** Initialize a recovery handle that creates a new database containing
2713 ** the recovered data.
2714 */
sqlite3_recover_init(sqlite3 * db,const char * zDb,const char * zUri)2715 sqlite3_recover *sqlite3_recover_init(
2716   sqlite3* db,
2717   const char *zDb,
2718   const char *zUri
2719 ){
2720   return recoverInit(db, zDb, zUri, 0, 0);
2721 }
2722 
2723 /*
2724 ** Initialize a recovery handle that returns recovered data in the
2725 ** form of SQL statements via a callback.
2726 */
sqlite3_recover_init_sql(sqlite3 * db,const char * zDb,int (* xSql)(void *,const char *),void * pSqlCtx)2727 sqlite3_recover *sqlite3_recover_init_sql(
2728   sqlite3* db,
2729   const char *zDb,
2730   int (*xSql)(void*, const char*),
2731   void *pSqlCtx
2732 ){
2733   return recoverInit(db, zDb, 0, xSql, pSqlCtx);
2734 }
2735 
2736 /*
2737 ** Return the handle error message, if any.
2738 */
sqlite3_recover_errmsg(sqlite3_recover * p)2739 const char *sqlite3_recover_errmsg(sqlite3_recover *p){
2740   return (p && p->errCode!=SQLITE_NOMEM) ? p->zErrMsg : "out of memory";
2741 }
2742 
2743 /*
2744 ** Return the handle error code.
2745 */
sqlite3_recover_errcode(sqlite3_recover * p)2746 int sqlite3_recover_errcode(sqlite3_recover *p){
2747   return p ? p->errCode : SQLITE_NOMEM;
2748 }
2749 
2750 /*
2751 ** Configure the handle.
2752 */
sqlite3_recover_config(sqlite3_recover * p,int op,void * pArg)2753 int sqlite3_recover_config(sqlite3_recover *p, int op, void *pArg){
2754   int rc = SQLITE_OK;
2755   if( p==0 ){
2756     rc = SQLITE_NOMEM;
2757   }else if( p->eState!=RECOVER_STATE_INIT ){
2758     rc = SQLITE_MISUSE;
2759   }else{
2760     switch( op ){
2761       case 789:
2762         /* This undocumented magic configuration option is used to set the
2763         ** name of the auxiliary database that is ATTACH-ed to the database
2764         ** connection and used to hold state information during the
2765         ** recovery process.  This option is for debugging use only and
2766         ** is subject to change or removal at any time. */
2767         sqlite3_free(p->zStateDb);
2768         p->zStateDb = recoverMPrintf(p, "%s", (char*)pArg);
2769         break;
2770 
2771       case SQLITE_RECOVER_LOST_AND_FOUND: {
2772         const char *zArg = (const char*)pArg;
2773         sqlite3_free(p->zLostAndFound);
2774         if( zArg ){
2775           p->zLostAndFound = recoverMPrintf(p, "%s", zArg);
2776         }else{
2777           p->zLostAndFound = 0;
2778         }
2779         break;
2780       }
2781 
2782       case SQLITE_RECOVER_FREELIST_CORRUPT:
2783         p->bFreelistCorrupt = *(int*)pArg;
2784         break;
2785 
2786       case SQLITE_RECOVER_ROWIDS:
2787         p->bRecoverRowid = *(int*)pArg;
2788         break;
2789 
2790       case SQLITE_RECOVER_SLOWINDEXES:
2791         p->bSlowIndexes = *(int*)pArg;
2792         break;
2793 
2794       default:
2795         rc = SQLITE_NOTFOUND;
2796         break;
2797     }
2798   }
2799 
2800   return rc;
2801 }
2802 
2803 /*
2804 ** Do a unit of work towards the recovery job. Return SQLITE_OK if
2805 ** no error has occurred but database recovery is not finished, SQLITE_DONE
2806 ** if database recovery has been successfully completed, or an SQLite
2807 ** error code if an error has occurred.
2808 */
sqlite3_recover_step(sqlite3_recover * p)2809 int sqlite3_recover_step(sqlite3_recover *p){
2810   if( p==0 ) return SQLITE_NOMEM;
2811   if( p->errCode==SQLITE_OK ) recoverStep(p);
2812   if( p->eState==RECOVER_STATE_DONE && p->errCode==SQLITE_OK ){
2813     return SQLITE_DONE;
2814   }
2815   return p->errCode;
2816 }
2817 
2818 /*
2819 ** Do the configured recovery operation. Return SQLITE_OK if successful, or
2820 ** else an SQLite error code.
2821 */
sqlite3_recover_run(sqlite3_recover * p)2822 int sqlite3_recover_run(sqlite3_recover *p){
2823   while( SQLITE_OK==sqlite3_recover_step(p) );
2824   return sqlite3_recover_errcode(p);
2825 }
2826 
2827 
2828 /*
2829 ** Free all resources associated with the recover handle passed as the only
2830 ** argument. The results of using a handle with any sqlite3_recover_**
2831 ** API function after it has been passed to this function are undefined.
2832 **
2833 ** A copy of the value returned by the first call made to sqlite3_recover_run()
2834 ** on this handle is returned, or SQLITE_OK if sqlite3_recover_run() has
2835 ** not been called on this handle.
2836 */
sqlite3_recover_finish(sqlite3_recover * p)2837 int sqlite3_recover_finish(sqlite3_recover *p){
2838   int rc;
2839   if( p==0 ){
2840     rc = SQLITE_NOMEM;
2841   }else{
2842     recoverFinalCleanup(p);
2843     if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){
2844       rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0);
2845       if( p->errCode==SQLITE_OK ) p->errCode = rc;
2846     }
2847     rc = p->errCode;
2848     sqlite3_free(p->zErrMsg);
2849     sqlite3_free(p->zStateDb);
2850     sqlite3_free(p->zLostAndFound);
2851     sqlite3_free(p->pPage1Cache);
2852     sqlite3_free(p);
2853   }
2854   return rc;
2855 }
2856 
2857 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
2858