1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // -----------------------------------------------------------------------------
17 // File: escaping.h
18 // -----------------------------------------------------------------------------
19 //
20 // This header file contains string utilities involved in escaping and
21 // unescaping strings in various ways.
22
23 #ifndef ABSL_STRINGS_ESCAPING_H_
24 #define ABSL_STRINGS_ESCAPING_H_
25
26 #include <cstddef>
27 #include <string>
28 #include <vector>
29
30 #include "absl/base/attributes.h"
31 #include "absl/base/macros.h"
32 #include "absl/base/nullability.h"
33 #include "absl/strings/ascii.h"
34 #include "absl/strings/str_join.h"
35 #include "absl/strings/string_view.h"
36
37 namespace absl {
38 ABSL_NAMESPACE_BEGIN
39
40 // CUnescape()
41 //
42 // Unescapes a `source` string and copies it into `dest`, rewriting C-style
43 // escape sequences (https://en.cppreference.com/w/cpp/language/escape) into
44 // their proper code point equivalents, returning `true` if successful.
45 //
46 // The following unescape sequences can be handled:
47 //
48 // * ASCII escape sequences ('\n','\r','\\', etc.) to their ASCII equivalents
49 // * Octal escape sequences ('\nnn') to byte nnn. The unescaped value must
50 // resolve to a single byte or an error will occur. E.g. values greater than
51 // 0xff will produce an error.
52 // * Hexadecimal escape sequences ('\xnn') to byte nn. While an arbitrary
53 // number of following digits are allowed, the unescaped value must resolve
54 // to a single byte or an error will occur. E.g. '\x0045' is equivalent to
55 // '\x45', but '\x1234' will produce an error.
56 // * Unicode escape sequences ('\unnnn' for exactly four hex digits or
57 // '\Unnnnnnnn' for exactly eight hex digits, which will be encoded in
58 // UTF-8. (E.g., `\u2019` unescapes to the three bytes 0xE2, 0x80, and
59 // 0x99).
60 //
61 // If any errors are encountered, this function returns `false`, leaving the
62 // `dest` output parameter in an unspecified state, and stores the first
63 // encountered error in `error`. To disable error reporting, set `error` to
64 // `nullptr` or use the overload with no error reporting below.
65 //
66 // Example:
67 //
68 // std::string s = "foo\\rbar\\nbaz\\t";
69 // std::string unescaped_s;
70 // if (!absl::CUnescape(s, &unescaped_s)) {
71 // ...
72 // }
73 // EXPECT_EQ(unescaped_s, "foo\rbar\nbaz\t");
74 bool CUnescape(absl::string_view source, absl::Nonnull<std::string*> dest,
75 absl::Nullable<std::string*> error);
76
77 // Overload of `CUnescape()` with no error reporting.
CUnescape(absl::string_view source,absl::Nonnull<std::string * > dest)78 inline bool CUnescape(absl::string_view source,
79 absl::Nonnull<std::string*> dest) {
80 return CUnescape(source, dest, nullptr);
81 }
82
83 // CEscape()
84 //
85 // Escapes a 'src' string using C-style escapes sequences
86 // (https://en.cppreference.com/w/cpp/language/escape), escaping other
87 // non-printable/non-whitespace bytes as octal sequences (e.g. "\377").
88 //
89 // Example:
90 //
91 // std::string s = "foo\rbar\tbaz\010\011\012\013\014\x0d\n";
92 // std::string escaped_s = absl::CEscape(s);
93 // EXPECT_EQ(escaped_s, "foo\\rbar\\tbaz\\010\\t\\n\\013\\014\\r\\n");
94 std::string CEscape(absl::string_view src);
95
96 // CHexEscape()
97 //
98 // Escapes a 'src' string using C-style escape sequences, escaping
99 // other non-printable/non-whitespace bytes as hexadecimal sequences (e.g.
100 // "\xFF").
101 //
102 // Example:
103 //
104 // std::string s = "foo\rbar\tbaz\010\011\012\013\014\x0d\n";
105 // std::string escaped_s = absl::CHexEscape(s);
106 // EXPECT_EQ(escaped_s, "foo\\rbar\\tbaz\\x08\\t\\n\\x0b\\x0c\\r\\n");
107 std::string CHexEscape(absl::string_view src);
108
109 // Utf8SafeCEscape()
110 //
111 // Escapes a 'src' string using C-style escape sequences, escaping bytes as
112 // octal sequences, and passing through UTF-8 characters without conversion.
113 // I.e., when encountering any bytes with their high bit set, this function
114 // will not escape those values, whether or not they are valid UTF-8.
115 std::string Utf8SafeCEscape(absl::string_view src);
116
117 // Utf8SafeCHexEscape()
118 //
119 // Escapes a 'src' string using C-style escape sequences, escaping bytes as
120 // hexadecimal sequences, and passing through UTF-8 characters without
121 // conversion.
122 std::string Utf8SafeCHexEscape(absl::string_view src);
123
124 // Base64Escape()
125 //
126 // Encodes a `src` string into a base64-encoded 'dest' string with padding
127 // characters. This function conforms with RFC 4648 section 4 (base64) and RFC
128 // 2045.
129 void Base64Escape(absl::string_view src, absl::Nonnull<std::string*> dest);
130 std::string Base64Escape(absl::string_view src);
131
132 // WebSafeBase64Escape()
133 //
134 // Encodes a `src` string into a base64 string, like Base64Escape() does, but
135 // outputs '-' instead of '+' and '_' instead of '/', and does not pad 'dest'.
136 // This function conforms with RFC 4648 section 5 (base64url).
137 void WebSafeBase64Escape(absl::string_view src,
138 absl::Nonnull<std::string*> dest);
139 std::string WebSafeBase64Escape(absl::string_view src);
140
141 // Base64Unescape()
142 //
143 // Converts a `src` string encoded in Base64 (RFC 4648 section 4) to its binary
144 // equivalent, writing it to a `dest` buffer, returning `true` on success. If
145 // `src` contains invalid characters, `dest` is cleared and returns `false`.
146 // If padding is included (note that `Base64Escape()` does produce it), it must
147 // be correct. In the padding, '=' and '.' are treated identically.
148 bool Base64Unescape(absl::string_view src, absl::Nonnull<std::string*> dest);
149
150 // WebSafeBase64Unescape()
151 //
152 // Converts a `src` string encoded in "web safe" Base64 (RFC 4648 section 5) to
153 // its binary equivalent, writing it to a `dest` buffer. If `src` contains
154 // invalid characters, `dest` is cleared and returns `false`. If padding is
155 // included (note that `WebSafeBase64Escape()` does not produce it), it must be
156 // correct. In the padding, '=' and '.' are treated identically.
157 bool WebSafeBase64Unescape(absl::string_view src,
158 absl::Nonnull<std::string*> dest);
159
160 // HexStringToBytes()
161 //
162 // Converts the hexadecimal encoded data in `hex` into raw bytes in the `bytes`
163 // output string. If `hex` does not consist of valid hexadecimal data, this
164 // function returns false and leaves `bytes` in an unspecified state. Returns
165 // true on success.
166 ABSL_MUST_USE_RESULT bool HexStringToBytes(absl::string_view hex,
167 absl::Nonnull<std::string*> bytes);
168
169 // HexStringToBytes()
170 //
171 // Converts an ASCII hex string into bytes, returning binary data of length
172 // `from.size()/2`. The input must be valid hexadecimal data, otherwise the
173 // return value is unspecified.
174 ABSL_DEPRECATED("Use the HexStringToBytes() that returns a bool")
175 std::string HexStringToBytes(absl::string_view from);
176
177 // BytesToHexString()
178 //
179 // Converts binary data into an ASCII text string, returning a string of size
180 // `2*from.size()`.
181 std::string BytesToHexString(absl::string_view from);
182
183 ABSL_NAMESPACE_END
184 } // namespace absl
185
186 #endif // ABSL_STRINGS_ESCAPING_H_
187