Merge cherrypicks of ['googleplex-android-review.googlesource.com/26752596'] into sc-v2-platform-release.
Change-Id: I46611fd3e6c0cc7fcd25a67a3172c220d2e0cad5
diff --git a/lib/libstatssocket/stats_event.c b/lib/libstatssocket/stats_event.c
index dcd34aa..948d042 100644
--- a/lib/libstatssocket/stats_event.c
+++ b/lib/libstatssocket/stats_event.c
@@ -266,6 +266,9 @@
// Side-effect: modifies event->errors if field has too many annotations
static void increment_annotation_count(AStatsEvent* event) {
+ if (event->lastFieldPos >= event->bufSize) {
+ return;
+ }
uint8_t fieldType = event->buf[event->lastFieldPos] & 0x0F;
uint32_t oldAnnotationCount = (event->buf[event->lastFieldPos] & 0xF0) >> 4;
uint32_t newAnnotationCount = oldAnnotationCount + 1;
diff --git a/lib/libstatssocket/tests/stats_event_test.cpp b/lib/libstatssocket/tests/stats_event_test.cpp
index 2f9ccdc..93a2944 100644
--- a/lib/libstatssocket/tests/stats_event_test.cpp
+++ b/lib/libstatssocket/tests/stats_event_test.cpp
@@ -426,6 +426,50 @@
AStatsEvent_release(event);
}
+TEST(StatsEventTest, TestHeapBufferOverflowError) {
+ const std::string testString(4039, 'A');
+ const std::string testString2(47135, 'B');
+
+ AStatsEvent* event = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(event, 100);
+
+ AStatsEvent_writeString(event, testString.c_str());
+ size_t bufferSize = 0;
+ AStatsEvent_getBuffer(event, &bufferSize);
+ EXPECT_EQ(bufferSize, 4060);
+ uint32_t errors = AStatsEvent_getErrors(event);
+ EXPECT_EQ(errors, 0);
+
+ // expand the buffer and fill with data up to the very last byte
+ AStatsEvent_writeString(event, testString2.c_str());
+ bufferSize = 0;
+ AStatsEvent_getBuffer(event, &bufferSize);
+ EXPECT_EQ(bufferSize, 50 * 1024);
+
+ errors = AStatsEvent_getErrors(event);
+ EXPECT_EQ(errors, 0);
+
+ // this write is no-op due to buffer reached its max capacity
+ // should set the overflow flag
+ AStatsEvent_writeString(event, testString2.c_str());
+ bufferSize = 0;
+ AStatsEvent_getBuffer(event, &bufferSize);
+ EXPECT_EQ(bufferSize, 50 * 1024);
+
+ errors = AStatsEvent_getErrors(event);
+ EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW);
+
+ // here should be crash
+ AStatsEvent_addBoolAnnotation(event, 1, false);
+
+ AStatsEvent_write(event);
+
+ errors = AStatsEvent_getErrors(event);
+ EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW);
+
+ AStatsEvent_release(event);
+}
+
TEST(StatsEventTest, TestPullOverflowError) {
const uint32_t atomId = 10100;
const vector<uint8_t> bytes(430 /* number of elements */, 1 /* value of each element */);