diff --git a/src/file_sql.c b/src/file_sql.c index 9c493732..39b36c09 100644 --- a/src/file_sql.c +++ b/src/file_sql.c @@ -29,7 +29,7 @@ #include #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=®ister_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); }