|
@@ -362,7 +362,7 @@ TString CEscapeInternal(y_absl::string_view src, bool use_hex,
|
|
|
}
|
|
|
|
|
|
/* clang-format off */
|
|
|
-constexpr unsigned char c_escaped_len[256] = {
|
|
|
+constexpr unsigned char kCEscapedLen[256] = {
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
|
1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", '
|
|
@@ -387,8 +387,23 @@ constexpr unsigned char c_escaped_len[256] = {
|
|
|
// that UTF-8 bytes are not handled specially.
|
|
|
inline size_t CEscapedLength(y_absl::string_view src) {
|
|
|
size_t escaped_len = 0;
|
|
|
- for (char c : src)
|
|
|
- escaped_len += c_escaped_len[static_cast<unsigned char>(c)];
|
|
|
+ // The maximum value of kCEscapedLen[x] is 4, so we can escape any string of
|
|
|
+ // length size_t_max/4 without checking for overflow.
|
|
|
+ size_t unchecked_limit =
|
|
|
+ std::min<size_t>(src.size(), std::numeric_limits<size_t>::max() / 4);
|
|
|
+ size_t i = 0;
|
|
|
+ while (i < unchecked_limit) {
|
|
|
+ // Common case: No need to check for overflow.
|
|
|
+ escaped_len += kCEscapedLen[static_cast<unsigned char>(src[i++])];
|
|
|
+ }
|
|
|
+ while (i < src.size()) {
|
|
|
+ // Beyond unchecked_limit we need to check for overflow before adding.
|
|
|
+ size_t char_len = kCEscapedLen[static_cast<unsigned char>(src[i++])];
|
|
|
+ Y_ABSL_INTERNAL_CHECK(
|
|
|
+ escaped_len <= std::numeric_limits<size_t>::max() - char_len,
|
|
|
+ "escaped_len overflow");
|
|
|
+ escaped_len += char_len;
|
|
|
+ }
|
|
|
return escaped_len;
|
|
|
}
|
|
|
|
|
@@ -400,12 +415,15 @@ void CEscapeAndAppendInternal(y_absl::string_view src, TString* dest) {
|
|
|
}
|
|
|
|
|
|
size_t cur_dest_len = dest->size();
|
|
|
+ Y_ABSL_INTERNAL_CHECK(
|
|
|
+ cur_dest_len <= std::numeric_limits<size_t>::max() - escaped_len,
|
|
|
+ "TString size overflow");
|
|
|
strings_internal::STLStringResizeUninitialized(dest,
|
|
|
cur_dest_len + escaped_len);
|
|
|
char* append_ptr = &(*dest)[cur_dest_len];
|
|
|
|
|
|
for (char c : src) {
|
|
|
- size_t char_len = c_escaped_len[static_cast<unsigned char>(c)];
|
|
|
+ size_t char_len = kCEscapedLen[static_cast<unsigned char>(c)];
|
|
|
if (char_len == 1) {
|
|
|
*append_ptr++ = c;
|
|
|
} else if (char_len == 2) {
|