Remove non-UTF8 characters from string fields.
The string type in the tombstone proto does not support non-UTF8
characters. Therefore, use the oct_encode function to encode the
abort_message field and message field from LogMessage.
Fix up stl includes, add ones that were missing and remove those not
being used.
Add new unit test to verify that the abort and log messages are
sanitized.
Bug: 279496937
Bug: 377940849
Bug: 378185483
Test: All unit tests pass.
Test: Ran pbtombstone on a crash with non-UTF8 characters and verified
Test: it processes properly after this change and fails before the change.
Change-Id: I3554d56caf9fcbfc410b4d554f6c3b4888b37e28
diff --git a/debuggerd/libdebuggerd/utility_host.cpp b/debuggerd/libdebuggerd/utility_host.cpp
index 72a560c..4efa03c 100644
--- a/debuggerd/libdebuggerd/utility_host.cpp
+++ b/debuggerd/libdebuggerd/utility_host.cpp
@@ -18,6 +18,8 @@
#include <sys/prctl.h>
+#include <charconv>
+#include <limits>
#include <string>
#include <android-base/stringprintf.h>
@@ -99,3 +101,24 @@
DESCRIBE_FLAG(PR_PAC_APGAKEY);
return describe_end(value, desc);
}
+
+std::string oct_encode(const std::string& data) {
+ std::string oct_encoded;
+ oct_encoded.reserve(data.size());
+
+ // N.B. the unsigned here is very important, otherwise e.g. \255 would render as
+ // \-123 (and overflow our buffer).
+ for (unsigned char c : data) {
+ if (isprint(c)) {
+ oct_encoded += c;
+ } else {
+ std::string oct_digits("\\\0\0\0", 4);
+ // char is encodable in 3 oct digits
+ static_assert(std::numeric_limits<unsigned char>::max() <= 8 * 8 * 8);
+ auto [ptr, ec] = std::to_chars(oct_digits.data() + 1, oct_digits.data() + 4, c, 8);
+ oct_digits.resize(ptr - oct_digits.data());
+ oct_encoded += oct_digits;
+ }
+ }
+ return oct_encoded;
+}