liblog: truncate logtags that overflow prefixBuf

Bug: 27585978
Change-Id: If2f45e8787b05b46491a771702746cfc248b9ccd
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 19a3e27..02df8dd 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -1429,8 +1429,16 @@
      * possibly causing heap corruption.  To avoid this we double check and
      * set the length at the maximum (size minus null byte)
      */
-    prefixLen += MIN(len, sizeof(prefixBuf) - prefixLen);
-    suffixLen = MIN(suffixLen, sizeof(suffixBuf));
+    prefixLen += len;
+    if (prefixLen >= sizeof(prefixBuf)) {
+        prefixLen = sizeof(prefixBuf) - 1;
+        prefixBuf[sizeof(prefixBuf) - 1] = '\0';
+    }
+    if (suffixLen >= sizeof(suffixBuf)) {
+        suffixLen = sizeof(suffixBuf) - 1;
+        suffixBuf[sizeof(suffixBuf) - 2] = '\n';
+        suffixBuf[sizeof(suffixBuf) - 1] = '\0';
+    }
 
     /* the following code is tragically unreadable */
 
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 50ecd2d..8893780 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -861,6 +861,60 @@
     EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
 }
 
+TEST(liblog, __android_log_buf_print__maxtag) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+    log_time ts(android_log_clockid());
+
+    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
+                                         max_payload_buf, max_payload_buf));
+    usleep(1000000);
+
+    int count = 0;
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+            break;
+        }
+
+        ASSERT_EQ(log_msg.entry.pid, pid);
+
+        if ((log_msg.entry.sec < (ts.tv_sec - 1))
+         || ((ts.tv_sec + 1) < log_msg.entry.sec)
+         || ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD)
+         || (log_msg.id() != LOG_ID_MAIN)) {
+            continue;
+        }
+
+        ++count;
+
+        AndroidLogFormat *logformat = android_log_format_new();
+        EXPECT_TRUE(NULL != logformat);
+        AndroidLogEntry entry;
+        int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
+                                                            &entry);
+        EXPECT_EQ(0, processLogBuffer);
+        if (processLogBuffer == 0) {
+            fflush(stderr);
+            int printLogLine =
+                    android_log_printLogLine(logformat, fileno(stderr), &entry);
+            EXPECT_LE(128, printLogLine);
+            EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD, printLogLine);
+        }
+        android_log_format_free(logformat);
+    }
+
+    EXPECT_EQ(1, count);
+
+    android_logger_list_close(logger_list);
+}
+
 TEST(liblog, too_big_payload) {
     pid_t pid = getpid();
     static const char big_payload_tag[] = "TEST_big_payload_XXXX";