From 309169a11864b05a031bda2cf11a3b6bf7054e0f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Apr 2007 17:27:51 +0000 Subject: [PATCH] When the write_version flag in the database header is larger than what the library understands, make the database read-only. The old behavior was to make the database unreadable. (CVS 3866) FossilOrigin-Name: 10648e99929b4f640855433b6e47702687039286 --- manifest | 13 +++++----- manifest.uuid | 2 +- src/btree.c | 19 +++++++++----- test/rdonly.test | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 test/rdonly.test diff --git a/manifest b/manifest index 966fb33c63..baab34ad37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\sbuild\sworking\swith\s-DSQLITE_OMIT_UTF16=1.\s\sTicket\s#2314.\s(CVS\s3865) -D 2007-04-23T23:56:31 +C When\sthe\swrite_version\sflag\sin\sthe\sdatabase\sheader\sis\slarger\sthan\swhat\nthe\slibrary\sunderstands,\smake\sthe\sdatabase\sread-only.\s\sThe\sold\sbehavior\nwas\sto\smake\sthe\sdatabase\sunreadable.\s(CVS\s3866) +D 2007-04-24T17:27:51 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -59,7 +59,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3 F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651 F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f -F src/btree.c bed25c6af7eb2cc4bd8a1d11acb4682a7f0a81e3 +F src/btree.c 16119ce57ff10217f15b0b4c86d176ee5335a94f F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf F src/build.c 1880da163d9aa404016242b8b76d69907f682cd8 F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e @@ -297,6 +297,7 @@ F test/printf.test 483b9fe75ffae1fb27328bdce5560b452ba83577 F test/progress.test 8b22b4974b0a95272566385f8cb8c341c7130df8 x F test/quick.test 8e7ffe36a1c920cdcce5d641646abde2dafd764b F test/quote.test 5891f2338980916cf7415484b4ce785294044adb +F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0 F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b F test/rollback.test 673cd8c44c685ad54987fe7f0eeba84efa09685d F test/rowid.test 040a3bef06f970c45f5fcd14b2355f7f4d62f0cf @@ -460,7 +461,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 94374654ccabb391f5dcccfc88176ca677c5804e -R d7b272e26c6d36664b64086fdb9d371b +P 25c1c7aaa8ef203120c2c242cf72ce4750f78abd +R 3fc076971d716b426bc268b75c0ef34b U drh -Z baebe6d339241fecad908b7b83716212 +Z 82843ae5ccf4a2ae39514c6de28aac15 diff --git a/manifest.uuid b/manifest.uuid index ea5f03a8ac..4701d9fc25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25c1c7aaa8ef203120c2c242cf72ce4750f78abd \ No newline at end of file +10648e99929b4f640855433b6e47702687039286 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 48f4f5676c..5eed902f30 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.356 2007/04/19 00:24:34 drh Exp $ +** $Id: btree.c,v 1.357 2007/04/24 17:27:51 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1870,7 +1870,10 @@ static int lockBtree(BtShared *pBt){ if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; } - if( page1[18]>1 || page1[19]>1 ){ + if( page1[18]>1 ){ + pBt->readOnly = 1; + } + if( page1[19]>1 ){ goto page1_init_failed; } pageSize = get2byte(&page1[16]); @@ -2068,11 +2071,15 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ if( pBt->pPage1==0 ){ rc = lockBtree(pBt); } - + if( rc==SQLITE_OK && wrflag ){ - rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1); - if( rc==SQLITE_OK ){ - rc = newDatabase(pBt); + if( pBt->readOnly ){ + rc = SQLITE_READONLY; + }else{ + rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + } } } diff --git a/test/rdonly.test b/test/rdonly.test new file mode 100644 index 0000000000..2f6ebc7a6c --- /dev/null +++ b/test/rdonly.test @@ -0,0 +1,65 @@ +# 2007 April 24 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to make sure SQLite treats a database +# as readonly if its write version is set to high. +# +# $Id: rdonly.test,v 1.1 2007/04/24 17:27:52 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + + +# Create a database. +# +do_test rdonly-1.1 { + execsql { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); + SELECT * FROM t1; + } +} {1} + +# Changes the write version from 1 to 2. Verify that the database +# can be read but not written. +# +do_test rdonly-1.2 { + db close + hexio_get_int [hexio_read test.db 18 1] +} 1 +do_test rdonly-1.3 { + hexio_write test.db 18 02 + sqlite3 db test.db + execsql { + SELECT * FROM t1; + } +} {1} +do_test rdonly-1.4 { + catchsql { + INSERT INTO t1 VALUES(2) + } +} {1 {attempt to write a readonly database}} + +# Change the write version back to 1. Verify that the database +# is read-write again. +# +do_test rdonly-1.5 { + db close + hexio_write test.db 18 01 + sqlite3 db test.db + catchsql { + INSERT INTO t1 VALUES(2); + SELECT * FROM t1; + } +} {0 {1 2}} + +finish_test