Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f31c5f56 authored by Muhammad Qureshi's avatar Muhammad Qureshi Committed by Jeffrey Huang
Browse files

Handle null values in AStatsEvent

- Treat NULL strings and byte arrays as zero-length strings/byte arrays.

This maintains backwards compatibility with legacy protocol which
handled nulls.

Bug: 155363739
Test: atest libstatssocket_test
Change-Id: I484b7c968270ae7228ea53bb97c7e6a2dbebe983
Merged-In: I484b7c968270ae7228ea53bb97c7e6a2dbebe983
(cherry picked from commit 7a19241f)
parent 1412c579
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -232,14 +232,19 @@ void AStatsEvent_writeBool(AStatsEvent* event, bool value) {

void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
    start_field(event, BYTE_ARRAY_TYPE);
    if (buf == NULL) {
        numBytes = 0;
    }
    append_int32(event, numBytes);
    if (numBytes > 0) {
        append_byte_array(event, buf, numBytes);
    }
}

// Value is assumed to be encoded using UTF8
void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
    start_field(event, STRING_TYPE);
    append_string(event, value);
    append_string(event, value == NULL ? "" : value);
}

// Tags are assumed to be encoded using UTF8
@@ -255,7 +260,7 @@ void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,

    for (uint8_t i = 0; i < numNodes; i++) {
        append_int32(event, uids[i]);
        append_string(event, tags[i]);
        append_string(event, tags[i] == NULL ? "" : tags[i]);
    }
}

+58 −2
Original line number Diff line number Diff line
@@ -183,6 +183,31 @@ TEST(StatsEventTest, TestStrings) {
    AStatsEvent_release(event);
}

TEST(StatsEventTest, TestNullString) {
    uint32_t atomId = 100;
    char* str = nullptr;

    int64_t startTime = android::elapsedRealtimeNano();
    AStatsEvent* event = AStatsEvent_obtain();
    AStatsEvent_setAtomId(event, atomId);
    AStatsEvent_writeString(event, str);
    AStatsEvent_build(event);
    int64_t endTime = android::elapsedRealtimeNano();

    size_t bufferSize;
    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
    uint8_t* bufferEnd = buffer + bufferSize;

    checkMetadata(&buffer, /*numElements=*/1, startTime, endTime, atomId);

    checkTypeHeader(&buffer, STRING_TYPE);
    checkString(&buffer, "");

    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
    AStatsEvent_release(event);
}

TEST(StatsEventTest, TestByteArrays) {
    uint32_t atomId = 100;
    vector<uint8_t> message = {'b', 'y', 't', '\0', 'e', 's'};
@@ -208,6 +233,32 @@ TEST(StatsEventTest, TestByteArrays) {
    AStatsEvent_release(event);
}

TEST(StatsEventTest, TestNullByteArrays) {
    uint32_t atomId = 100;
    uint8_t* buf = nullptr;
    vector<uint8_t> message;

    int64_t startTime = android::elapsedRealtimeNano();
    AStatsEvent* event = AStatsEvent_obtain();
    AStatsEvent_setAtomId(event, atomId);
    AStatsEvent_writeByteArray(event, buf, 2);
    AStatsEvent_build(event);
    int64_t endTime = android::elapsedRealtimeNano();

    size_t bufferSize;
    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
    uint8_t* bufferEnd = buffer + bufferSize;

    checkMetadata(&buffer, /*numElements=*/1, startTime, endTime, atomId);

    checkTypeHeader(&buffer, BYTE_ARRAY_TYPE);
    checkByteArray(&buffer, message);

    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
    AStatsEvent_release(event);
}

TEST(StatsEventTest, TestAttributionChains) {
    uint32_t atomId = 100;

@@ -217,9 +268,14 @@ TEST(StatsEventTest, TestAttributionChains) {
    const char* cTags[numNodes];
    for (int i = 0; i < (int)numNodes; i++) {
        uids[i] = i;
        if (0 == i) {
            tags.push_back("");
            cTags[i] = nullptr;
        } else {
            tags.push_back("test" + std::to_string(i));
            cTags[i] = tags[i].c_str();
        }
    }

    int64_t startTime = android::elapsedRealtimeNano();
    AStatsEvent* event = AStatsEvent_obtain();