os/persistentdata/persistentstorage/sql/TEST/t_sqlcorrupt.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // 
    15 //
    16 #include <e32test.h>
    17 #include <bautils.h>
    18 #include <sqldb.h>
    19 #include <stdlib.h>
    20 #include "sqlite3.h"
    21 #include "SqliteSymbian.h"
    22 
    23 ///////////////////////////////////////////////////////////////////////////////////////
    24 
    25 RSqlDatabase TheDb;
    26 RTest TheTest(_L("t_sqlcorrupt test"));
    27 
    28 _LIT(KTestDir, "c:\\test\\");
    29 
    30 _LIT(KDbName, "c:[08770000]t_sqlcorrupt.db");
    31 _LIT(KFullDbName, "c:\\private\\10281E17\\[08770000]t_sqlcorrupt.db");
    32 
    33 _LIT(KDbName2, "c:[08770000]t_sqlcorrupt2.db");
    34 _LIT(KFullDbName2, "c:\\private\\10281E17\\[08770000]t_sqlcorrupt2.db");
    35 
    36 RFs TheFs;
    37 
    38 ///////////////////////////////////////////////////////////////////////////////////////
    39 
    40 void DestroyTestEnv()
    41 	{
    42 	TheDb.Close();
    43 	(void)RSqlDatabase::Delete(KDbName2);
    44 	(void)RSqlDatabase::Delete(KDbName);
    45 	TheFs.Close();
    46 	}
    47 
    48 ///////////////////////////////////////////////////////////////////////////////////////
    49 //Test macros and functions
    50 void Check1(TInt aValue, TInt aLine)
    51 	{
    52 	if(!aValue)
    53 		{
    54 		DestroyTestEnv();
    55 		RDebug::Print(_L("*** Boolean expression evaluated to false. Line %d\r\n"), aLine);
    56 		TheTest(EFalse, aLine);
    57 		}
    58 	}
    59 void Check2(TInt aValue, TInt aExpected, TInt aLine)
    60 	{
    61 	if(aValue != aExpected)
    62 		{
    63 		DestroyTestEnv();
    64 		RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
    65 		TheTest(EFalse, aLine);
    66 		}
    67 	}
    68 #define TEST(arg) ::Check1((arg), __LINE__)
    69 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
    70 
    71 ///////////////////////////////////////////////////////////////////////////////////////
    72 
    73 RSqlSecurityPolicy CreateTestSecurityPolicy()
    74 	{
    75 	RSqlSecurityPolicy policy;
    76 	TInt err = policy.Create(TSecurityPolicy::EAlwaysPass);
    77 	TEST2(err, KErrNone);
    78 
    79 	err = policy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, TSecurityPolicy::EAlwaysPass);
    80 	TEST2(err, KErrNone);
    81 	err = policy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, TSecurityPolicy::EAlwaysPass);
    82 	TEST2(err, KErrNone);
    83 	err = policy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, TSecurityPolicy::EAlwaysPass);
    84 	TEST2(err, KErrNone);
    85 
    86 	err = policy.SetPolicy(RSqlSecurityPolicy::ETable, _L("A"), RSqlSecurityPolicy::EWritePolicy, TSecurityPolicy::EAlwaysPass);
    87 	TEST2(err, KErrNone);
    88 	err = policy.SetPolicy(RSqlSecurityPolicy::ETable, _L("A"), RSqlSecurityPolicy::EReadPolicy, TSecurityPolicy::EAlwaysPass);
    89 	TEST2(err, KErrNone);
    90 	
    91 	return policy;
    92 	}
    93 
    94 enum TDbEncoding
    95 	{
    96 	EDbEncUtf16,
    97 	EDbEncUtf8,
    98 	};
    99 
   100 void DoCorruptedSecureDbTest(TDbEncoding aEncoding)
   101 	{
   102 	(void)RSqlDatabase::Delete(KDbName);
   103 	
   104 	RSqlSecurityPolicy policy = CreateTestSecurityPolicy();
   105 	TInt err = KErrNone;
   106 	if(aEncoding == EDbEncUtf16)
   107 		{
   108 		err = TheDb.Create(KDbName, policy);
   109 		}
   110 	else
   111 		{
   112 		_LIT8(KConfig, "encoding = \"UTF-8\"");
   113 		err = TheDb.Create(KDbName, policy, &KConfig);
   114 		}
   115 	TEST2(err, KErrNone);
   116 	err = TheDb.Exec(_L("CREATE TABLE A(I INTEGER); INSERT INTO A VALUES(10)"));
   117 	TEST(err >= 0);
   118 	TheDb.Close();
   119 	policy.Close();
   120 
   121 	CFileMan* fm = NULL;
   122 	TRAP(err, fm = CFileMan::NewL(TheFs));
   123 	TEST2(err, KErrNone);
   124 	
   125 	//Make a copy of the database
   126 	err = fm->Copy(KFullDbName, KFullDbName2);
   127 	TEST2(err, KErrNone);
   128 	//Get the database file size and calculate the iterations count.
   129 	TEntry entry;
   130 	err = TheFs.Entry(KFullDbName, entry);
   131 	TEST2(err, KErrNone);
   132 	const TInt KCorruptBlockLen = 19;
   133 	const TInt KIterationCnt = entry.iSize / KCorruptBlockLen;
   134 	//
   135 	TBuf8<KCorruptBlockLen> invalidData;
   136 	invalidData.SetLength(KCorruptBlockLen);
   137 	TChar invalidChar[] = {TChar((TUint)0xCC), TChar(0x00), TChar((TUint)-1), TChar(0x1D)};
   138 	for(TInt j=0;j<(sizeof(invalidChar)/sizeof(invalidChar[0]));++j)
   139 		{
   140 		invalidData.Fill(invalidChar[j]);
   141 		TheTest.Printf(_L("Invalid char: %X\r\n"), (TUint)(invalidChar[j]));
   142 		for(TInt i=0;i<KIterationCnt;++i)
   143 			{
   144 			TheTest.Printf(_L("% 4d\r"), i + 1);
   145 			//Corrupt the database
   146 			err = fm->Copy(KFullDbName2, KFullDbName);
   147 			TEST2(err, KErrNone);
   148 			RFile file;
   149 			err = file.Open(TheFs, KFullDbName, EFileRead | EFileWrite);
   150 			TEST2(err, KErrNone);
   151 			TInt fpos = i * KCorruptBlockLen;
   152 			err = file.Write(fpos, invalidData);
   153 			TEST2(err, KErrNone);
   154 			file.Close();
   155 			//Try to open the database and read the record
   156 			TBool testPassed = EFalse;
   157 			err = TheDb.Open(KDbName);
   158 			if(err == KErrNone)
   159 				{
   160 				RSqlStatement stmt;
   161 				err = stmt.Prepare(TheDb, _L("SELECT I FROM A"));
   162 				if(err == KErrNone)
   163 					{
   164 					err = stmt.Next();
   165 					if(err == KSqlAtRow)
   166 						{
   167 						TInt val = stmt.ColumnInt(0);
   168 						if(val == 10)
   169 							{
   170 							testPassed = ETrue;
   171 							err = KErrNone;
   172 							}
   173 						else
   174 							{
   175 							err = KErrGeneral;
   176 							}
   177 						}
   178 					stmt.Close();
   179 					}
   180 				}
   181 
   182 			TheDb.Close();
   183 			(void)RSqlDatabase::Delete(KDbName);
   184 			TheTest.Printf(_L("Iteration % 4d, err=%d\r\n"), i + 1, err);
   185 			if(!testPassed)
   186 				{
   187 				TEST(err != KErrNone);
   188 				}
   189 			}//end of - for(TInt i=0;i<KIterationCnt;++i)
   190 		TheTest.Printf(_L("\r\n"));
   191 		}
   192 	(void)fm->Delete(KFullDbName2);
   193 	delete fm;
   194 	}
   195 
   196 /**
   197 @SYMTestCaseID          PDS-SQL-CT-4202
   198 @SYMTestCaseDesc        Invalid UTF16 encoded secure database test.
   199 @SYMTestPriority        High
   200 @SYMTestActions         The test creates 16-bit encoded secure database with one table and one record.
   201 						Then the test simulates a database corruption by writing 19 bytes with random values
   202 						from "pos" to "pos + 19", where "pos" is a valid db file position, incremented by 19
   203 						at the end of each test iteration.
   204 @SYMTestExpectedResults Test must not fail
   205 */  
   206 void CorruptedSecureDbTest16()
   207 	{
   208 	DoCorruptedSecureDbTest(EDbEncUtf16);
   209 	}
   210 
   211 /**
   212 @SYMTestCaseID          PDS-SQL-CT-4202
   213 @SYMTestCaseDesc        Invalid UTF8 encoded secure database test.
   214 @SYMTestPriority        High
   215 @SYMTestActions         The test creates 8-bit encoded secure database with one table and one record.
   216 						Then the test simulates a database corruption by writing 19 bytes with random values
   217 						from "pos" to "pos + 19", where "pos" is a valid db file position, incremented by 19
   218 						at the end of each test iteration.
   219 @SYMTestExpectedResults Test must not fail
   220 */  
   221 void CorruptedSecureDbTest8()
   222 	{
   223 	DoCorruptedSecureDbTest(EDbEncUtf8);
   224 	}
   225 
   226 const TInt KDbPolicyTypeTooSmall = 1;
   227 const TInt KDbPolicyTypeTooBig = 2;
   228 const TInt KDefaultPolicyWithObjName = 3;
   229 const TInt KDbPolicyWithObjName = 4;
   230 const TInt KInvObjPolicyWithObjName = 5;
   231 const TInt KDefaultPolicyMoved = 6;
   232 const TInt KDuplicatedDbPolicy = 7;
   233 const TInt KTablePolicyTypeTooSmall = 8;
   234 const TInt KTablePolicyTypeTooBig = 9;
   235 const TInt KTablePolicyNameInvalid = 10;
   236 const TInt KTwoDefaultPolicies = 11;
   237 
   238 void CorruptDbPolicy(TInt aType)
   239 	{
   240 	TBuf8<200> dbName;
   241 	dbName.Copy(KFullDbName());
   242 	sqlite3* dbHandle = NULL;
   243 	TInt err = sqlite3_open((const char*)(dbName.PtrZ()), &dbHandle);
   244 	TEST2(err, SQLITE_OK);
   245 	switch(aType)
   246 		{
   247 		case KDbPolicyTypeTooSmall: //Invalid database poicy type - less than the schema policy type
   248 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET PolicyType=-10 WHERE ObjectType=-1 AND PolicyType=0", NULL, 0, NULL);
   249 			TEST2(err, SQLITE_OK);
   250 			break;
   251 		case KDbPolicyTypeTooBig: //Invalid database poicy type - bigger than the write policy type
   252 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET PolicyType=10 WHERE ObjectType=-1 AND PolicyType=0", NULL, 0, NULL);
   253 			TEST2(err, SQLITE_OK);
   254 			break;
   255 		case KDefaultPolicyWithObjName: //Default database policy with valid object name 
   256 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET ObjectName='aaaa' WHERE ObjectType=-2", NULL, 0, NULL);
   257 			TEST2(err, SQLITE_OK);
   258 			break;
   259 		case KDbPolicyWithObjName: //Database policy with valid object name 
   260 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET ObjectName='aaaa' WHERE ObjectType=-1", NULL, 0, NULL);
   261 			TEST2(err, SQLITE_OK);
   262 			break;
   263 		case KInvObjPolicyWithObjName: //Invalid object type is with valid object name
   264 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET ObjectType=5, ObjectName='aaaa' WHERE ObjectType=0", NULL, 0, NULL);
   265 			TEST2(err, SQLITE_OK);
   266 			break;
   267 		case KDefaultPolicyMoved: //The default security policy is the last in the table
   268 			err = sqlite3_exec(dbHandle, "DELETE FROM symbian_security WHERE ObjectType=-2", NULL, 0, NULL);
   269 			TEST2(err, SQLITE_OK);
   270 			err = sqlite3_exec(dbHandle, "INSERT INTO symbian_security VALUES(20,-2,'',0, x'1122334455667788')", NULL, 0, NULL);
   271 			TEST2(err, SQLITE_OK);
   272 			break;
   273 		case KDuplicatedDbPolicy: //Two database policies of the same type
   274 			err = sqlite3_exec(dbHandle, "INSERT INTO symbian_security VALUES(9,-1,'',1, x'1122334455667788')", NULL, 0, NULL);
   275 			TEST2(err, SQLITE_OK);
   276 			break;
   277 		case KTablePolicyTypeTooSmall: //Invalid table poicy type - less than the read policy type
   278 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET PolicyType=-10 WHERE ObjectType=0 AND PolicyType=1", NULL, 0, NULL);
   279 			TEST2(err, SQLITE_OK);
   280 			break;
   281 		case KTablePolicyTypeTooBig: //Invalid table poicy type - less than the write policy type
   282 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET PolicyType=10 WHERE ObjectType=0 AND PolicyType=2", NULL, 0, NULL);
   283 			TEST2(err, SQLITE_OK);
   284 			break;
   285 		case KTablePolicyNameInvalid:
   286 			err = sqlite3_exec(dbHandle, "UPDATE symbian_security SET ObjectName='' WHERE ObjectType=0 AND PolicyType=2", NULL, 0, NULL);
   287 			TEST2(err, SQLITE_OK);
   288 			break;
   289 		case KTwoDefaultPolicies:
   290 			err = sqlite3_exec(dbHandle, "INSERT INTO symbian_security VALUES(9,-2,'',1, x'1122334455667788')", NULL, 0, NULL);
   291 			TEST2(err, SQLITE_OK);
   292 			break;
   293 		default:
   294 			TEST(0);
   295 			break;
   296 		}
   297 	sqlite3_close(dbHandle);
   298 	}
   299 
   300 /**
   301 @SYMTestCaseID          PDS-SQL-CT-4240
   302 @SYMTestCaseDesc        Invalid settings in symbian_security table.
   303 @SYMTestPriority        High
   304 @SYMTestActions         The test creates a secure test database. Then the test runs a set of test 
   305 						 iterations. On each itertaion the test makes onle of the stored security 
   306 						 policies invalied (symbian_security table). Then the test attempts to open 
   307 						 the database and checks the behaviour of the SQL server - whether an error
   308 						 will be reproted back or not.
   309 @SYMTestExpectedResults Test must not fail
   310 */  
   311 void BadDbPolicyTest()
   312 	{
   313 	sqlite3SymbianLibInit();    
   314 	
   315 	RSqlSecurityPolicy policy = CreateTestSecurityPolicy();
   316 	//
   317 	(void)RSqlDatabase::Delete(KDbName);
   318 	TInt err = TheDb.Create(KDbName, policy);
   319 	TEST2(err, KErrNone);
   320 	err = TheDb.Exec(_L("CREATE TABLE A(I INTEGER); INSERT INTO A VALUES(10)"));
   321 	TEST(err >= 0);
   322 	TheDb.Close();
   323 	policy.Close();
   324 	//
   325 	CFileMan* fm = NULL;
   326 	TRAP(err, fm = CFileMan::NewL(TheFs));
   327 	TEST2(err, KErrNone);
   328 	//Make a copy of the database
   329 	err = fm->Copy(KFullDbName, KFullDbName2);
   330 	TEST2(err, KErrNone);
   331 	//Invalid database policy - policy type value less than the schema policy type value
   332 	CorruptDbPolicy(KDbPolicyTypeTooSmall);
   333 	err = TheDb.Open(KDbName);
   334 	TheDb.Close();
   335 	TEST2(err, KErrGeneral);
   336 	err = fm->Copy(KFullDbName2, KFullDbName);
   337 	TEST2(err, KErrNone);
   338 	//Invalid database policy - policy type value bigger than the write policy type value
   339 	CorruptDbPolicy(KDbPolicyTypeTooBig);
   340 	err = TheDb.Open(KDbName);
   341 	TheDb.Close();
   342 	TEST2(err, KErrGeneral);
   343 	err = fm->Copy(KFullDbName2, KFullDbName);
   344 	TEST2(err, KErrNone);
   345 	//Invalid database policy - the default database policy is with valid object name
   346 	CorruptDbPolicy(KDefaultPolicyWithObjName);
   347 	err = TheDb.Open(KDbName);
   348 	TheDb.Close();
   349 	TEST2(err, KErrNone);
   350 	err = fm->Copy(KFullDbName2, KFullDbName);
   351 	TEST2(err, KErrNone);
   352 	//Invalid database policy - database policy is with valid object name
   353 	CorruptDbPolicy(KDbPolicyWithObjName);
   354 	err = TheDb.Open(KDbName);
   355 	TheDb.Close();
   356 	TEST2(err, KErrNone);
   357 	err = fm->Copy(KFullDbName2, KFullDbName);
   358 	TEST2(err, KErrNone);
   359 	//Invalid database policy - invalid object type is with valid object name
   360 	CorruptDbPolicy(KInvObjPolicyWithObjName);
   361 	err = TheDb.Open(KDbName);
   362 	TheDb.Close();
   363 	TEST2(err, KErrGeneral);
   364 	err = fm->Copy(KFullDbName2, KFullDbName);
   365 	TEST2(err, KErrNone);
   366 	//Invalid database policy - the default security policy is the last in the table
   367 	CorruptDbPolicy(KDefaultPolicyMoved);
   368 	err = TheDb.Open(KDbName);
   369 	TheDb.Close();
   370 	TEST2(err, KErrNone);
   371 	err = fm->Copy(KFullDbName2, KFullDbName);
   372 	TEST2(err, KErrNone);
   373 	//Invalid database policy - duplicated database policy
   374 	CorruptDbPolicy(KDuplicatedDbPolicy);
   375 	err = TheDb.Open(KDbName);
   376 	TheDb.Close();
   377 	TEST2(err, KErrGeneral);
   378 	err = fm->Copy(KFullDbName2, KFullDbName);
   379 	TEST2(err, KErrNone);
   380 	//Invalid table policy - policy type value less than the read policy type value
   381 	CorruptDbPolicy(KTablePolicyTypeTooSmall);
   382 	err = TheDb.Open(KDbName);
   383 	TheDb.Close();
   384 	TEST2(err, KErrGeneral);
   385 	err = fm->Copy(KFullDbName2, KFullDbName);
   386 	TEST2(err, KErrNone);
   387 	//Invalid table policy - policy type value bigger than the write policy type value
   388 	CorruptDbPolicy(KTablePolicyTypeTooBig);
   389 	err = TheDb.Open(KDbName);
   390 	TheDb.Close();
   391 	TEST2(err, KErrGeneral);
   392 	err = fm->Copy(KFullDbName2, KFullDbName);
   393 	TEST2(err, KErrNone);
   394 	//Invalid table policy - emtpy string as a table name 
   395 	CorruptDbPolicy(KTablePolicyNameInvalid);
   396 	err = TheDb.Open(KDbName);
   397 	TheDb.Close();
   398 	TEST2(err, KErrGeneral);
   399 	err = fm->Copy(KFullDbName2, KFullDbName);
   400 	TEST2(err, KErrNone);
   401 	//Two default policies
   402 	CorruptDbPolicy(KTwoDefaultPolicies);
   403 	err = TheDb.Open(KDbName);
   404 	TheDb.Close();
   405 	TEST2(err, KErrGeneral);
   406 	err = fm->Copy(KFullDbName2, KFullDbName);
   407 	TEST2(err, KErrNone);
   408 	//
   409 	(void)RSqlDatabase::Delete(KDbName);
   410 	(void)fm->Delete(KFullDbName2);
   411 	delete fm;
   412 	
   413 	sqlite3SymbianLibFinalize();
   414 	CloseSTDLIB();
   415 	}
   416 
   417 
   418 void CreateTestEnv()
   419     {
   420     TInt err = TheFs.Connect();
   421     TEST2(err, KErrNone);
   422 
   423     err = TheFs.MkDir(KTestDir);
   424     TEST(err == KErrNone || err == KErrAlreadyExists);
   425 
   426     err = TheFs.CreatePrivatePath(EDriveC);
   427     TEST(err == KErrNone || err == KErrAlreadyExists);
   428     }
   429 
   430 void DoTestsL()
   431 	{
   432 	TheTest.Start(_L("@SYMTestCaseID:PDS-SQL-CT-4202 Corrupted UTF16 encoded secure database test"));
   433 	CorruptedSecureDbTest16();
   434 	
   435 	TheTest.Next(_L("@SYMTestCaseID:PDS-SQL-CT-4203 Corrupted UTF8 encoded secure database test"));
   436 	CorruptedSecureDbTest8();
   437 	
   438 	TheTest.Next(_L("@SYMTestCaseID:PDS-SQL-CT-4240 Secure database with bad policy test"));
   439 	BadDbPolicyTest();
   440 	}
   441 
   442 TInt E32Main()
   443 	{
   444 	TheTest.Title();
   445 	
   446 	CTrapCleanup* tc = CTrapCleanup::New();
   447 	TheTest(tc != NULL);
   448 	
   449 	__UHEAP_MARK;
   450 		
   451 	CreateTestEnv();
   452 	TRAPD(err, DoTestsL());
   453 	DestroyTestEnv();
   454 	TEST2(err, KErrNone);
   455 
   456 	__UHEAP_MARKEND;
   457 	
   458 	TheTest.End();
   459 	TheTest.Close();
   460 	
   461 	delete tc;
   462 
   463 	User::Heap().Check();
   464 	return KErrNone;
   465 	}