1 // Copyright (c) 2020 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 "quiche/common/test_tools/quiche_test_utils.h"
6
7 #include <string>
8
9 #include "quiche/common/platform/api/quiche_googleurl.h"
10 #include "quiche/common/platform/api/quiche_logging.h"
11 #include "quiche/common/platform/api/quiche_test.h"
12
13 namespace {
14
HexDumpWithMarks(const char * data,int length,const bool * marks,int mark_length)15 std::string HexDumpWithMarks(const char* data, int length, const bool* marks,
16 int mark_length) {
17 static const char kHexChars[] = "0123456789abcdef";
18 static const int kColumns = 4;
19
20 const int kSizeLimit = 1024;
21 if (length > kSizeLimit || mark_length > kSizeLimit) {
22 QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
23 length = std::min(length, kSizeLimit);
24 mark_length = std::min(mark_length, kSizeLimit);
25 }
26
27 std::string hex;
28 for (const char* row = data; length > 0;
29 row += kColumns, length -= kColumns) {
30 for (const char* p = row; p < row + 4; ++p) {
31 if (p < row + length) {
32 const bool mark =
33 (marks && (p - data) < mark_length && marks[p - data]);
34 hex += mark ? '*' : ' ';
35 hex += kHexChars[(*p & 0xf0) >> 4];
36 hex += kHexChars[*p & 0x0f];
37 hex += mark ? '*' : ' ';
38 } else {
39 hex += " ";
40 }
41 }
42 hex = hex + " ";
43
44 for (const char* p = row; p < row + 4 && p < row + length; ++p) {
45 hex += (*p >= 0x20 && *p < 0x7f) ? (*p) : '.';
46 }
47
48 hex = hex + '\n';
49 }
50 return hex;
51 }
52
53 } // namespace
54
55 namespace quiche {
56 namespace test {
57
CompareCharArraysWithHexError(const std::string & description,const char * actual,const int actual_len,const char * expected,const int expected_len)58 void CompareCharArraysWithHexError(const std::string& description,
59 const char* actual, const int actual_len,
60 const char* expected,
61 const int expected_len) {
62 EXPECT_EQ(actual_len, expected_len);
63 const int min_len = std::min(actual_len, expected_len);
64 const int max_len = std::max(actual_len, expected_len);
65 std::unique_ptr<bool[]> marks(new bool[max_len]);
66 bool identical = (actual_len == expected_len);
67 for (int i = 0; i < min_len; ++i) {
68 if (actual[i] != expected[i]) {
69 marks[i] = true;
70 identical = false;
71 } else {
72 marks[i] = false;
73 }
74 }
75 for (int i = min_len; i < max_len; ++i) {
76 marks[i] = true;
77 }
78 if (identical) return;
79 ADD_FAILURE() << "Description:\n"
80 << description << "\n\nExpected:\n"
81 << HexDumpWithMarks(expected, expected_len, marks.get(),
82 max_len)
83 << "\nActual:\n"
84 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
85 }
86
MakeIOVector(absl::string_view str)87 iovec MakeIOVector(absl::string_view str) {
88 return iovec{const_cast<char*>(str.data()), static_cast<size_t>(str.size())};
89 }
90
GoogleUrlSupportsIdnaForTest()91 bool GoogleUrlSupportsIdnaForTest() {
92 const std::string kTestInput = "https://\xe5\x85\x89.example.org/";
93 const std::string kExpectedOutput = "https://xn--54q.example.org/";
94
95 GURL url(kTestInput);
96 bool valid = url.is_valid() && url.spec() == kExpectedOutput;
97 QUICHE_CHECK(valid || !url.is_valid()) << url.spec();
98 return valid;
99 }
100
101 } // namespace test
102 } // namespace quiche
103