summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/file_sql.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/src/file_sql.c b/src/file_sql.c
index 9c49373..39b36c0 100644
--- a/src/file_sql.c
+++ b/src/file_sql.c
@@ -29,7 +29,7 @@
#include <stdio.h>
#include "types.h"
#include "filegen.h"
-
+#include "common.h"
static void register_header_check_sqlite(file_stat_t *file_stat);
static int header_check_sqlite(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
@@ -44,24 +44,53 @@ const file_hint_t file_hint_sqlite= {
.register_header_check=&register_header_check_sqlite
};
-static const unsigned char sqlite_header[15]= {'S','Q','L','i','t','e',' ','f','o','r','m','a','t',' ','3'};
-
-static void register_header_check_sqlite(file_stat_t *file_stat)
+/* http://www.sqlite.org/fileformat.html */
+struct db_header
{
- register_header_check(0, sqlite_header,sizeof(sqlite_header), &header_check_sqlite, file_stat);
-}
+ char magic[16];
+ uint16_t pagesize;
+ uint8_t ffwrite;
+ uint8_t ffread;
+ uint8_t reserved;
+ uint8_t max_emb_payload_frac;
+ uint8_t min_emb_payload_frac;
+ uint8_t leaf_payload_frac;
+ uint32_t file_change_counter;
+ uint32_t filesize_in_page;
+ uint32_t first_freelist_page;
+ uint32_t freelist_pages;
+ uint32_t schema_cookie;
+ uint32_t schema_format;
+ uint32_t default_page_cache_size;
+ uint32_t largest_root_btree;
+ uint32_t text_encoding;
+ uint32_t user_version;
+ uint32_t inc_vacuum_mode;
+ uint32_t app_id;
+ char reserved_for_expansion[20];
+ uint32_t version_valid_for;
+ uint32_t version;
+} __attribute__ ((__packed__));
static int header_check_sqlite(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
- if(memcmp(buffer,sqlite_header,sizeof(sqlite_header))==0)
- {
- reset_file_recovery(file_recovery_new);
+ const struct db_header *hdr=(const struct db_header *)buffer;
+ const unsigned int pagesize=be16(hdr->pagesize);
+ /* Must be a power of two between 512 and 32768 inclusive, or the value 1 representing a page size of 65536. */
+ if(pagesize!=1 &&
+ (pagesize<512 || ((pagesize-1) & pagesize)!=0))
+ return 0;
+ reset_file_recovery(file_recovery_new);
#ifdef DJGPP
- file_recovery_new->extension="sql";
+ file_recovery_new->extension="sql";
#else
- file_recovery_new->extension=file_hint_sqlite.extension;
+ file_recovery_new->extension=file_hint_sqlite.extension;
#endif
- return 1;
- }
- return 0;
+ file_recovery_new->min_filesize=sizeof(struct db_header);
+ return 1;
+}
+
+static void register_header_check_sqlite(file_stat_t *file_stat)
+{
+ register_header_check(0, "SQLite format 3", 16, &header_check_sqlite, file_stat);
}