1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/spdy/hpack_string_util.h" 6 7 #include <cstddef> 8 #include <cstring> 9 10 #include "base/basictypes.h" 11 #include "base/logging.h" 12 #include "base/strings/string_piece.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace net { 16 17 namespace { 18 19 using std::string; 20 21 // Make sure StringPiecesEqualConstantTime() behaves like the regular 22 // string equality operator. 23 TEST(HpackStringUtilTest, StringPiecesEqualConstantTime) { 24 EXPECT_TRUE(StringPiecesEqualConstantTime("foo", "foo")); 25 EXPECT_FALSE(StringPiecesEqualConstantTime("foo", "foox")); 26 EXPECT_FALSE(StringPiecesEqualConstantTime("foo", "bar")); 27 } 28 29 // TODO(jgraettinger): Support this benchmark. 30 /* 31 enum BM_StringPieceEqualityType { 32 STRCMP_EQUAL, 33 STRCMP_FIRST_CHAR_DIFFERS, 34 STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL, 35 STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS, 36 }; 37 38 void BM_StringPieceEquality(int iters, int size, int type_int) { 39 BM_StringPieceEqualityType type = 40 static_cast<BM_StringPieceEqualityType>(type_int); 41 string str_a(size, 'x'); 42 string str_b(size, 'x'); 43 int result = 0; 44 switch (type) { 45 case STRCMP_EQUAL: 46 for (int i = 0; i < iters; ++i) { 47 result |= std::strcmp(str_a.c_str(), str_b.c_str()); 48 } 49 CHECK_EQ(result, 0); 50 return; 51 52 case STRCMP_FIRST_CHAR_DIFFERS: 53 str_b[0] = 'y'; 54 for (int i = 0; i < iters; ++i) { 55 result |= std::strcmp(str_a.c_str(), str_b.c_str()); 56 } 57 CHECK_LT(result, 0); 58 return; 59 60 case STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL: 61 for (int i = 0; i < iters; ++i) { 62 result |= StringPiecesEqualConstantTime(str_a, str_b); 63 } 64 CHECK_EQ(result, 1); 65 return; 66 67 case STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS: 68 str_b[0] = 'y'; 69 for (int i = 0; i < iters; ++i) { 70 result |= StringPiecesEqualConstantTime(str_a, str_b); 71 } 72 CHECK_EQ(result, 0); 73 return; 74 } 75 76 DCHECK(false); 77 } 78 79 // Results should resemble the table below, where 0 and 1 are clearly 80 // different (STRCMP), but 2 and 3 are roughly the same 81 // (STRING_PIECES_EQUAL_CONSTANT_TIME). 82 // 83 // DEBUG: Benchmark Time(ns) CPU(ns) Iterations 84 // ------------------------------------------------------------------- 85 // DEBUG: BM_StringPieceEquality/1M/0 77796 77141 7778 86 // DEBUG: BM_StringPieceEquality/1M/1 10 10 70000000 87 // DEBUG: BM_StringPieceEquality/1M/2 7729735 7700000 100 88 // DEBUG: BM_StringPieceEquality/1M/3 7803051 7800000 100 89 BENCHMARK(BM_StringPieceEquality) 90 ->ArgPair(1<<20, STRCMP_EQUAL) 91 ->ArgPair(1<<20, STRCMP_FIRST_CHAR_DIFFERS) 92 ->ArgPair(1<<20, STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL) 93 ->ArgPair(1<<20, STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS); 94 */ 95 96 } // namespace 97 98 } // namespace net 99