From e883653170572848a4436b91ebe8a0e984f61c58 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Fri, 8 Oct 2021 12:53:36 -0400 Subject: [PATCH] switch to flexible cipher_test pragma for controlling test failures --- src/crypto.c | 28 ++++++++++++---------------- src/crypto.h | 6 ++++++ test/sqlcipher-codecerror.test | 16 ++++++++-------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 5a181a88..d9c888fe 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -40,8 +40,7 @@ #endif #ifdef SQLCIPHER_TEST -static int cipher_fail_next_encrypt = 0; -static int cipher_fail_next_decrypt = 0; +static int cipher_test_flags = 0; #endif /* Generate code to return a string value */ @@ -117,20 +116,17 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef } else #endif #ifdef SQLCIPHER_TEST - if( sqlite3StrICmp(zLeft,"cipher_fail_next_encrypt")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_test")==0 ){ if( zRight ) { - cipher_fail_next_encrypt = sqlite3GetBoolean(zRight,1); - } else { - char *fail = sqlite3_mprintf("%d", cipher_fail_next_encrypt); - codec_vdbe_return_string(pParse, "cipher_fail_next_encrypt", fail, P4_DYNAMIC); - } - }else - if( sqlite3StrICmp(zLeft,"cipher_fail_next_decrypt")==0 ){ - if( zRight ) { - cipher_fail_next_decrypt = sqlite3GetBoolean(zRight,1); + if(sqlite3StrICmp(zRight, "fail_next_encrypt")) { + cipher_test_flags ^= TEST_FAIL_NEXT_ENCRYPT; + } else + if(sqlite3StrICmp(zRight, "fail_next_decrypt")) { + cipher_test_flags ^= TEST_FAIL_NEXT_DECRYPT; + } } else { - char *fail = sqlite3_mprintf("%d", cipher_fail_next_decrypt); - codec_vdbe_return_string(pParse, "cipher_fail_next_decrypt", fail, P4_DYNAMIC); + char *flags = sqlite3_mprintf("%d", cipher_test_flags); + codec_vdbe_return_string(pParse, "cipher_test", flags, P4_DYNAMIC); } }else #endif @@ -718,7 +714,7 @@ static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset); #ifdef SQLCIPHER_TEST - if(cipher_fail_next_decrypt) rc = SQLITE_ERROR; + if((cipher_test_flags & TEST_FAIL_NEXT_ENCRYPT) > 0) rc = SQLITE_ERROR; #endif if(rc != SQLITE_OK) { /* clear results of failed cipher operation and set error */ sqlcipher_memset((unsigned char*) buffer+offset, 0, page_sz-offset); @@ -743,7 +739,7 @@ static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { } rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset); #ifdef SQLCIPHER_TEST - if(cipher_fail_next_encrypt) rc = SQLITE_ERROR; + if((cipher_test_flags & TEST_FAIL_NEXT_DECRYPT) > 0) rc = SQLITE_ERROR; #endif if(rc != SQLITE_OK) { /* clear results of failed cipher operation and set error */ sqlcipher_memset((unsigned char*)buffer+offset, 0, page_sz-offset); diff --git a/src/crypto.h b/src/crypto.h index 1b2e3dc9..49e7080d 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -191,6 +191,12 @@ static int cipher_isHex(const unsigned char *hex, int sz){ return 1; } +/* possible flags for simulating specific test conditions */ +#ifdef SQLCIPHER_TEST +#define TEST_FAIL_NEXT_ENCRYPT (1ul << 0) /* 1 */ +#define TEST_FAIL_NEXT_DECRYPT (1ul << 1) /* 2 */ +#endif + /* extensions defined in crypto_impl.c */ /* the default implementation of SQLCipher uses a cipher_ctx to keep track of read / write state separately. The following diff --git a/test/sqlcipher-codecerror.test b/test/sqlcipher-codecerror.test index f481aaf2..927e8d19 100644 --- a/test/sqlcipher-codecerror.test +++ b/test/sqlcipher-codecerror.test @@ -66,7 +66,7 @@ do_test codec-error-journal-delete { catchsql { PRAGMA key = 'testkey'; - PRAGMA cipher_fail_next_encrypt = 1; + PRAGMA cipher_test = fail_next_encrypt; UPDATE t1 SET b = 'fail' WHERE a = 5000; } @@ -74,7 +74,7 @@ do_test codec-error-journal-delete { sqlite_orig db test.db execsql { - PRAGMA cipher_fail_next_encrypt = 0; + PRAGMA cipher_test = fail_next_encrypt; PRAGMA key = 'testkey'; PRAGMA cipher_integrity_check; PRAGMA integrity_check; @@ -92,7 +92,7 @@ do_test codec-error-journal-wal { catchsql { PRAGMA key = 'testkey'; - PRAGMA cipher_fail_next_encrypt = 1; + PRAGMA cipher_test = fail_next_encrypt; UPDATE t1 SET b = 'fail' WHERE a = 5000; } @@ -100,7 +100,7 @@ do_test codec-error-journal-wal { sqlite_orig db test.db execsql { - PRAGMA cipher_fail_next_encrypt = 0; + PRAGMA cipher_test = fail_next_encrypt; PRAGMA key = 'testkey'; PRAGMA cipher_integrity_check; PRAGMA integrity_check; @@ -120,7 +120,7 @@ do_test codec-error-journal-wal-transaction { PRAGMA key = 'testkey'; BEGIN; UPDATE t1 SET b = 'success' WHERE a = 1; - PRAGMA cipher_fail_next_encrypt = 1; + PRAGMA cipher_test = fail_next_encrypt; UPDATE t1 SET b = 'fail' WHERE a = 5000; COMMIT; } @@ -129,7 +129,7 @@ do_test codec-error-journal-wal-transaction { sqlite_orig db test.db execsql { - PRAGMA cipher_fail_next_encrypt = 0; + PRAGMA cipher_test = fail_next_encrypt; PRAGMA key = 'testkey'; PRAGMA cipher_integrity_check; PRAGMA integrity_check; @@ -149,7 +149,7 @@ do_test codec-error-journal-wal-read { catchsql { PRAGMA key = 'testkey'; SELECT count(*) FROM sqlite_schema; - PRAGMA cipher_fail_next_decrypt = 1; + PRAGMA cipher_test = fail_next_decrypt; UPDATE t1 SET b = 'fail' WHERE a = 5000; } @@ -157,7 +157,7 @@ do_test codec-error-journal-wal-read { sqlite_orig db test.db execsql { - PRAGMA cipher_fail_next_decrypt = 0; + PRAGMA cipher_test = fail_next_decrypt; PRAGMA key = 'testkey'; PRAGMA cipher_integrity_check; PRAGMA integrity_check; -- 2.11.4.GIT