PR #2102: guard size overflow in BytesToHexString and UrlEscape Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/2102 BytesToHexString sizes its output as 2 * from.size() and UrlEscapeInternal as initial_portion + 3 * (input.size() - initial_portion), neither of which checks for a size_t overflow, so a large enough input wraps the length and StringResizeAndOverwrite allocates a buffer smaller than the number of bytes the following loop writes into it. CEscapedLength and CalculateBase64EscapedLenInternal in this same file already guard their expansions against size_t max with ABSL_INTERNAL_CHECK, so these two newer helpers just add the matching check with the appropriate divisor. Merge d08c46485a00ab31af1ef8f06c2d9f7d4fa9d39e into 4890d3073b027fe5b5c541ca8d5b71daaecb2370 Merging this change closes #2102 COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/2102 from nabhan06:escaping-size-overflow-guard d08c46485a00ab31af1ef8f06c2d9f7d4fa9d39e PiperOrigin-RevId: 944523718 Change-Id: Ie10b04ed0f7f0aa0fc17aa33c028eba9cf7a0f61
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index e9119ca..bdbc7ce 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc
@@ -1177,6 +1177,8 @@ std::string BytesToHexString(absl::string_view from) { std::string result; + ABSL_INTERNAL_CHECK(from.size() <= std::numeric_limits<size_t>::max() / 2, + "BytesToHexString() overflow"); StringResizeAndOverwrite( result, 2 * from.size(), [from](char* buf, size_t buf_size) { absl::BytesToHexStringInternal( @@ -1211,6 +1213,10 @@ // We need a buffer with enough space to store at most the initial portion // plus 3 bytes for each remaining character since escapes use 3 characters. + ABSL_INTERNAL_CHECK( + (input.size() - initial_portion) <= + (std::numeric_limits<size_t>::max() - initial_portion) / 3, + "UrlEscape() overflow"); StringResizeAndOverwrite( output, initial_portion + 3 * (input.size() - initial_portion), [&](char* buf, size_t) {