proxygen
StructuredHeadersUtilities.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 
12 #include <boost/archive/iterators/binary_from_base64.hpp>
13 #include <boost/archive/iterators/base64_from_binary.hpp>
14 #include <boost/archive/iterators/transform_width.hpp>
16 
17 namespace proxygen {
18 namespace StructuredHeaders {
19 
20 bool isLcAlpha(char c) {
21  return c >= 0x61 && c <= 0x7A;
22 }
23 
25  return isLcAlpha(c) || std::isdigit(c) || c == '_' || c == '-' || c == '*' ||
26  c == '/';
27 }
28 
30  char c) {
31  return std::isalpha(c) || std::isdigit(c) || c == '+' || c == '/' || c == '=';
32 }
33 
34 bool isValidStringChar(char c) {
35  /*
36  * The difference between the character restriction here and that mentioned
37  * in section 3.7 of version 6 of the Structured Headers draft is that this
38  * function accepts \ and DQUOTE characters. These characters are allowed
39  * as long as they are present as a part of an escape sequence, which is
40  * checked for in the parseString() function in the StructuredHeadersBuffer.
41  */
42  return c >= 0x20 && c <= 0x7E;
43 }
44 
46  if (s.size() == 0 || !isLcAlpha(s[0])) {
47  return false;
48  }
49 
50  for (char c : s) {
51  if (!isValidIdentifierChar(c)) {
52  return false;
53  }
54  }
55 
56  return true;
57 }
58 
59 bool isValidString(const std::string& s) {
60  for (char c : s) {
61  if (!isValidStringChar(c)) {
62  return false;
63  }
64  }
65  return true;
66 }
67 
69  const std::string& s) {
70 
71  if (s.size() % 4 != 0) {
72  return false;
73  }
74 
75  bool equalSeen = false;
76  for (auto it = s.begin(); it != s.end(); it++) {
77  if (*it == '=') {
78  equalSeen = true;
79  } else if (equalSeen || !isValidEncodedBinaryContentChar(*it)) {
80  return false;
81  }
82  }
83 
84  return true;
85 }
86 
88  const StructuredHeaderItem& input) {
89  switch (input.tag) {
93  return input.value.type() == typeid(std::string);
95  return input.value.type() == typeid(int64_t);
97  return input.value.type() == typeid(double);
99  return true;
100  }
101 
102  return false;
103 }
104 
106  const std::string& encoded) {
107 
108  if (encoded.size() == 0) {
109  // special case, to prevent an integer overflow down below.
110  return "";
111  }
112 
113  using namespace boost::archive::iterators;
114  using b64it =
115  transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
116 
117  std::string decoded = std::string(b64it(std::begin(encoded)),
118  b64it(std::end(encoded)));
119 
120  uint32_t numPadding = std::count(encoded.begin(), encoded.end(), '=');
121  decoded.erase(decoded.end() - numPadding, decoded.end());
122 
123  return decoded;
124 }
125 
127  using namespace boost::archive::iterators;
128  using b64it = base64_from_binary<transform_width<const char*, 6, 8>>;
129 
130  auto data = input.data();
131  std::string encoded(b64it(data), b64it(data + (input.length())));
132  encoded.append((3 - (input.length() % 3)) % 3, '=');
133 
134  return encoded;
135 }
136 
137 }
138 }
bool isValidIdentifier(const std::string &s)
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
bool itemTypeMatchesContent(const StructuredHeaderItem &input)
std::string encodeBase64(const std::string &input)
boost::variant< int64_t, double, std::string > value
std::string decodeBase64(const std::string &encoded)
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
int * count
const char * string
Definition: Conv.cpp:212
bool isValidEncodedBinaryContent(const std::string &s)
static set< string > s
bool isValidString(const std::string &s)
char c
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43