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

Commit 18678bdc authored by Yi Jin's avatar Yi Jin
Browse files

Empty output if compact fails.

There must be equal number of start/end calls with right token given in
order, if used in wrong order, ProtoOutputStream will have empty output.

Also refactor Android.bp, so the gtest is standalone unit test, it used
to require compile/push libprotoutil.so to device.

Bug: 77342154
Test: atest libprotoutil_test
Change-Id: I0011bbab34c04cb38164d2ed21cd818d52a2ecf9
parent 50817a4c
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -12,9 +12,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

cc_library {
    name: "libprotoutil",
cc_defaults {
    name: "libprotoutil_defaults",

    cflags: [
        "-Wall",
@@ -30,8 +29,6 @@ cc_library {
        "src/protobuf.cpp",
    ],

    export_include_dirs: ["include"],

    shared_libs: [
        "libbase",
        "libcutils",
@@ -39,15 +36,24 @@ cc_library {
    ],
}

cc_library {
    name: "libprotoutil",

    defaults: ["libprotoutil_defaults"],

    export_include_dirs: ["include"],
}

cc_test {
    name: "libprotoutil_test",

    defaults: ["libprotoutil_defaults"],

    local_include_dirs: ["include"],

    srcs: ["tests/*"],

    shared_libs: [
        "libbase",
        "libcutils",
        "libprotoutil",
        "libprotobuf-cpp-full",
    ],

+1 −1
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ public:
    /**
     * Starts a sub-message write session.
     * Returns a token of this write session.
     * Must call end(token) when finish write this sub-message.
     * Must call end(token) exactly once when finish write this sub-message.
     */
    uint64_t start(uint64_t fieldId);
    void end(uint64_t token);
+5 −3
Original line number Diff line number Diff line
@@ -244,12 +244,14 @@ ProtoOutputStream::end(uint64_t token)
{
    if (token != mExpectedObjectToken) {
        ALOGE("Unexpected token: 0x%" PRIx64 ", should be 0x%" PRIx64, token, mExpectedObjectToken);
        mDepth = UINT32_C(-1); // make depth invalid
        return;
    }

    uint32_t depth = getDepthFromToken(token);
    if (depth != (mDepth & 0x01ff)) {
        ALOGE("Unexpected depth: %" PRIu32 ", should be %" PRIu32, depth, mDepth);
        mDepth = UINT32_C(-1); // make depth invalid
        return;
    }
    mDepth--;
@@ -282,7 +284,7 @@ bool
ProtoOutputStream::compact() {
    if (mCompact) return true;
    if (mDepth != 0) {
        ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing calls to end.", mDepth);
        ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing or extra calls to end.", mDepth);
        return false;
    }
    // record the size of the original buffer.
@@ -425,7 +427,7 @@ ProtoOutputStream::size()
{
    if (!compact()) {
        ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
        // TODO: handle this error
        return 0;
    }
    return mBuffer.size();
}
@@ -449,7 +451,7 @@ ProtoOutputStream::data()
{
    if (!compact()) {
        ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
        // TODO: handle this error
        mBuffer.clear();
    }
    return mBuffer.begin();
}
+37 −1
Original line number Diff line number Diff line
@@ -190,3 +190,39 @@ TEST(ProtoOutputStreamTest, InvalidTypes) {
    EXPECT_FALSE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, 18.73f));
    EXPECT_EQ(proto.size(), 0);
}

TEST(ProtoOutputStreamTest, NoEndCalled) {
    ProtoOutputStream proto;
    proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
    // no proto.end called
    EXPECT_NE(proto.bytesWritten(), 0);
    EXPECT_EQ(proto.size(), 0);
    EXPECT_EQ(proto.data().size(), 0);
    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
}


TEST(ProtoOutputStreamTest, TwoEndCalled) {
    ProtoOutputStream proto;
    uint64_t token = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
    proto.end(token);
    proto.end(token);
    EXPECT_NE(proto.bytesWritten(), 0);
    EXPECT_EQ(proto.size(), 0);
    EXPECT_EQ(proto.data().size(), 0);
    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
}

TEST(ProtoOutputStreamTest, NoStartCalled) {
    ProtoOutputStream proto;
    uint64_t wrongToken = UINT64_C(324536345);
    // no proto.start called
    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
    proto.end(wrongToken);
    EXPECT_NE(proto.bytesWritten(), 0);
    EXPECT_EQ(proto.size(), 0);
    EXPECT_EQ(proto.data().size(), 0);
    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
}