15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_types.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_params.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_opcodes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_GLOBAL_RTL(member) \
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  g_nt.member = reinterpret_cast<member##Function>( \
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::GetProcAddress(ntdll, #member)); \
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (NULL == g_nt.member) \
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT NtExports g_nt;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetupNtdllImports() {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMODULE ntdll = ::GetModuleHandle(kNtdllName);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlAllocateHeap);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlCompareUnicodeString);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlCreateHeap);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlDestroyHeap);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(RtlFreeHeap);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(_strnicmp);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(strlen);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INIT_GLOBAL_RTL(wcslen);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, ParameterSetTest) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* pv1 = reinterpret_cast<void*>(0x477EAA5);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* pv2 = reinterpret_cast<void*>(0x987654);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pset1 = ParamPickerMake(pv1);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pset2 = ParamPickerMake(pv2);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can store and retrieve a void pointer:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* result1 =0;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long result2 = 0;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pset1.Get(&result1));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pv1 == result1);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(pset1.Get(&result2));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pset2.Get(&result1));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pv2 == result1);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(pset2.Get(&result2));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can store and retrieve a ulong:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long number = 12747;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pset3 = ParamPickerMake(number);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(pset3.Get(&result1));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pset3.Get(&result2));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(number, result2);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can store and retrieve a string:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* txt = L"S231L";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pset4 = ParamPickerMake(txt);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* result3 = NULL;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pset4.Get(&result3));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, wcscmp(txt, result3));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeConstraints) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that PolicyOpcode has no virtual functions
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because these objects are copied over to other processes
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so they cannot have vtables.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(__is_polymorphic(PolicyOpcode));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep developers from adding smarts to the opcodes which should
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be pretty much a bag of bytes with a OO interface.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(__has_trivial_destructor(PolicyOpcode));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(__has_trivial_constructor(PolicyOpcode));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(__has_trivial_copy(PolicyOpcode));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, TrueFalseOpcodes) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* dummy = NULL;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet ppb1 = ParamPickerMake(dummy);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[1024];
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This opcode always evaluates to true.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&ppb1, 1, NULL));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(op1->IsAction());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This opcode always evaluates to false.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op2 = opcode_maker.MakeOpAlwaysTrue(kPolNone);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nulls not allowed on the params.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 0, NULL));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 1, NULL));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True and False opcodes do not 'require' a number of parameters
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 0, NULL));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test Inverting the logic. Note that inversion is done outside
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any particular opcode evaluation so no need to repeat for all
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // opcodes.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op3 = opcode_maker.MakeOpAlwaysFalse(kPolNegateEval);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&ppb1, 1, NULL));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op4 = opcode_maker.MakeOpAlwaysTrue(kPolNegateEval);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op4->Evaluate(&ppb1, 1, NULL));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we clear the match context
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op5 = opcode_maker.MakeOpAlwaysTrue(kPolClearContext);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext context;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context.position = 1;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context.options = kPolUseOREval;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&ppb1, 1, &context));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, context.position);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext context2;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(context2.options, context.options);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeMakerCase1) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing that the opcode maker does not overrun the
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied buffer. It should only be able to make 'count' opcodes.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* dummy = NULL;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet ppb1 = ParamPickerMake(dummy);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[256];
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = sizeof(memory) / sizeof(PolicyOpcode);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ix =0; ix != count; ++ix) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     PolicyOpcode* op = opcode_maker.MakeOpAlwaysFalse(kPolNone);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     ASSERT_TRUE(NULL != op);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     EXPECT_EQ(EVAL_FALSE, op->Evaluate(&ppb1, 1, NULL));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no room more another opcode:
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(NULL == op1);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeMakerCase2) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupNtdllImports();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing that the opcode maker does not overrun the
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied buffer. It should only be able to make 'count' opcodes.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The difference with the previous test is that this opcodes allocate
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the string 'txt2' inside the same buffer.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* txt1 = L"1234";
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt2[] = L"123";
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet ppb1 = ParamPickerMake(txt1);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext mc1;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[256];
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = sizeof(memory) / (sizeof(PolicyOpcode) + sizeof(txt2));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that it does not overrun the buffer.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ix =0; ix != count; ++ix) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PolicyOpcode* op = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       CASE_SENSITIVE,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       kPolClearContext);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(NULL != op);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(EVAL_TRUE, op->Evaluate(&ppb1, 1, &mc1));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no room more another opcode:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      kPolNone);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(NULL == op1);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, IntegerOpcodes) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* txt = L"abcdef";
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long num1 = 42;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long num2 = 113377;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_wrong1 = ParamPickerMake(txt);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_num1 = ParamPickerMake(num1);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_num2 = ParamPickerMake(num2);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[128];
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test basic match for unsigned longs 42 == 42 and 42 != 113377.
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  PolicyOpcode* op_m42 = opcode_maker.MakeOpNumberMatch(0, 42UL, kPolNone);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op_m42->Evaluate(&pp_num1, 1, NULL));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op_m42->Evaluate(&pp_num2, 1, NULL));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_ERROR, op_m42->Evaluate(&pp_wrong1, 1, NULL));
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test basic match for void pointers.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* vp = NULL;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_num3 = ParamPickerMake(vp);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op_vp_null = opcode_maker.MakeOpVoidPtrMatch(0, NULL,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                             kPolNone);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op_vp_null->Evaluate(&pp_num3, 1, NULL));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op_vp_null->Evaluate(&pp_num1, 1, NULL));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_ERROR, op_vp_null->Evaluate(&pp_wrong1, 1, NULL));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Basic range test [41 43] (inclusive).
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op_range1 = opcode_maker.MakeOpUlongMatchRange(0, 41, 43,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                               kPolNone);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op_range1->Evaluate(&pp_num1, 1, NULL));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op_range1->Evaluate(&pp_num2, 1, NULL));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_ERROR, op_range1->Evaluate(&pp_wrong1, 1, NULL));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, LogicalOpcodes) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[128];
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long num1 = 0x10100702;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_num1 = ParamPickerMake(num1);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op_and1 = opcode_maker.MakeOpUlongAndMatch(0, 0x00100000,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           kPolNone);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op_and1->Evaluate(&pp_num1, 1, NULL));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op_and2 = opcode_maker.MakeOpUlongAndMatch(0, 0x00000001,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           kPolNone);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op_and2->Evaluate(&pp_num1, 1, NULL));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, WCharOpcodes1) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupNtdllImports();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* txt1 = L"the quick fox jumps over the lazy dog";
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt2[] = L"the quick";
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt3[] = L" fox jumps";
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt4[] = L"the lazy dog";
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt5[] = L"jumps over";
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt6[] = L"g";
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_tc1 = ParamPickerMake(txt1);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[512];
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      kPolNone);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simplest substring match from pos 0. It should be a successful match
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the match context should be updated.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext mc1;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op1->Evaluate(&pp_tc1, 1, &mc1));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Matching again should fail and the context should be unmodified.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&pp_tc1, 1, &mc1));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Using the same match context we should continue where we left
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the previous successful match,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op3 = opcode_maker.MakeOpWStringMatch(0, txt3, 0,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      kPolNone);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&pp_tc1, 1, &mc1));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(_countof(txt3) + _countof(txt2) == mc1.position + 2);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now keep on matching but now we skip 6 characters which means
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we skip the string ' over '. And we zero the match context. This is
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the primitive that we use to build '??'.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op4 = opcode_maker.MakeOpWStringMatch(0, txt4, 6,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      kPolClearContext);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op4->Evaluate(&pp_tc1, 1, &mc1));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mc1.position);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can properly match the last part of the string
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op4b = opcode_maker.MakeOpWStringMatch(0, txt4, kSeekToEnd,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       CASE_SENSITIVE,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       kPolClearContext);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op4b->Evaluate(&pp_tc1, 1, &mc1));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mc1.position);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test matching 'jumps over' over the entire string. This is the
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // primitive we build '*' from.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op5 = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekForward,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE, kPolNone);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&pp_tc1, 1, &mc1));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(24, mc1.position);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we don't match because it is not at the end of the string
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op5b = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekToEnd,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       CASE_SENSITIVE,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       kPolNone);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op5b->Evaluate(&pp_tc1, 1, &mc1));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we function if the string does not fit. In this case we
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // try to match 'the lazy dog' against 'he lazy dog'.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op6 = opcode_maker.MakeOpWStringMatch(0, txt4, 2,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE, kPolNone);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(24, mc1.position);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing matching against 'g' which should be the last char.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext mc2;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op7 = opcode_maker.MakeOpWStringMatch(0, txt6, kSeekForward,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE, kPolNone);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op7->Evaluate(&pp_tc1, 1, &mc2));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trying to match again should fail since we are in the last char.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This also covers a couple of boundary conditions.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op7->Evaluate(&pp_tc1, 1, &mc2));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, WCharOpcodes2) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupNtdllImports();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* path1 = L"c:\\documents and settings\\Microsoft\\BLAH.txt";
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t txt1[] = L"Settings\\microsoft";
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet pp_tc1 = ParamPickerMake(path1);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[256];
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext mc1;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing case-insensitive does not buy us much since it this option
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is just passed to the Microsoft API that we use normally, but just for
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coverage, here it is:
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1s = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      CASE_SENSITIVE, kPolNone);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1i = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       CASE_INSENSITIVE,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       kPolNone);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_FALSE, op1s->Evaluate(&pp_tc1, 1, &mc1));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(EVAL_TRUE, op1i->Evaluate(&pp_tc1, 1, &mc1));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(35, mc1.position);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, ActionOpcodes) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char memory[256];
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpcodeFactory opcode_maker(memory, sizeof(memory));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MatchContext mc1;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* dummy = NULL;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParameterSet ppb1 = ParamPickerMake(dummy);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyOpcode* op1 = opcode_maker.MakeOpAction(ASK_BROKER, kPolNone);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(op1->IsAction());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASK_BROKER, op1->Evaluate(&ppb1, 1, &mc1));
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sandbox
344