summaryrefslogtreecommitdiffstats
path: root/logd
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2015-09-02 07:39:53 -0700
committerSteve Kondik <steve@cyngn.com>2015-11-01 04:29:12 -0800
commitc5a324fe084901a93215498f983703e483d9c000 (patch)
tree2de4fecf9739c88134280ffda3570fd34ab06c58 /logd
parent064c3a5ea2bdc8a0332f8d7d1c40f593c4b2ff1f (diff)
downloadsystem_core-c5a324fe084901a93215498f983703e483d9c000.zip
system_core-c5a324fe084901a93215498f983703e483d9c000.tar.gz
system_core-c5a324fe084901a93215498f983703e483d9c000.tar.bz2
logd: log_strtok_r deal with nuls
Rename to log_strntok_r and change from dealing with strings to dealing with a string and an associated length. Bug: 23517551 Change-Id: Ia72f1305a53f55eeef9861ac378fb8205fd2378e
Diffstat (limited to 'logd')
-rw-r--r--logd/LogKlog.cpp82
-rw-r--r--logd/LogKlog.h2
-rw-r--r--logd/main.cpp15
3 files changed, 67 insertions, 32 deletions
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 4064de1..242d7a0 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -39,14 +39,15 @@ static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' };
// Parsing is hard
// called if we see a '<', s is the next character, returns pointer after '>'
-static char *is_prio(char *s) {
- if (!isdigit(*s++)) {
+static char *is_prio(char *s, size_t len) {
+ if (!len || !isdigit(*s++)) {
return NULL;
}
- static const size_t max_prio_len = 4;
- size_t len = 0;
+ --len;
+ static const size_t max_prio_len = (len < 4) ? len : 4;
+ size_t priolen = 0;
char c;
- while (((c = *s++)) && (++len <= max_prio_len)) {
+ while (((c = *s++)) && (++priolen <= max_prio_len)) {
if (!isdigit(c)) {
return ((c == '>') && (*s == '[')) ? s : NULL;
}
@@ -55,16 +56,19 @@ static char *is_prio(char *s) {
}
// called if we see a '[', s is the next character, returns pointer after ']'
-static char *is_timestamp(char *s) {
- while (*s == ' ') {
+static char *is_timestamp(char *s, size_t len) {
+ while (len && (*s == ' ')) {
++s;
+ --len;
}
- if (!isdigit(*s++)) {
+ if (!len || !isdigit(*s++)) {
return NULL;
}
+ --len;
bool first_period = true;
char c;
- while ((c = *s++)) {
+ while (len && ((c = *s++))) {
+ --len;
if ((c == '.') && first_period) {
first_period = false;
} else if (!isdigit(c)) {
@@ -87,7 +91,11 @@ static char *is_timestamp(char *s) {
// space is one more than <digit> of 9
#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10))
-char *log_strtok_r(char *s, char **last) {
+char *log_strntok_r(char *s, size_t *len, char **last, size_t *sublen) {
+ *sublen = 0;
+ if (!*len) {
+ return NULL;
+ }
if (!s) {
if (!(s = *last)) {
return NULL;
@@ -97,6 +105,7 @@ char *log_strtok_r(char *s, char **last) {
if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) {
*s = (*s & ~SIGNATURE_MASK) + '0';
*--s = '<';
+ ++*len;
}
// fixup for log signature split [,
// OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit>
@@ -107,24 +116,30 @@ char *log_strtok_r(char *s, char **last) {
*s = (*s & ~SIGNATURE_MASK) + '0';
}
*--s = '[';
+ ++*len;
}
}
- s += strspn(s, "\r\n");
+ while (*len && ((*s == '\r') || (*s == '\n'))) {
+ ++s;
+ --*len;
+ }
- if (!*s) { // no non-delimiter characters
+ if (!*len) {
*last = NULL;
return NULL;
}
char *peek, *tok = s;
for (;;) {
- char c = *s++;
- switch (c) {
- case '\0':
+ if (*len == 0) {
*last = NULL;
return tok;
-
+ }
+ char c = *s++;
+ --*len;
+ size_t adjust;
+ switch (c) {
case '\r':
case '\n':
s[-1] = '\0';
@@ -132,7 +147,7 @@ char *log_strtok_r(char *s, char **last) {
return tok;
case '<':
- peek = is_prio(s);
+ peek = is_prio(s, *len);
if (!peek) {
break;
}
@@ -143,14 +158,26 @@ char *log_strtok_r(char *s, char **last) {
*last = s;
return tok;
}
+ adjust = peek - s;
+ if (adjust > *len) {
+ adjust = *len;
+ }
+ *sublen += adjust;
+ *len -= adjust;
s = peek;
- if ((*s == '[') && ((peek = is_timestamp(s + 1)))) {
+ if ((*s == '[') && ((peek = is_timestamp(s + 1, *len - 1)))) {
+ adjust = peek - s;
+ if (adjust > *len) {
+ adjust = *len;
+ }
+ *sublen += adjust;
+ *len -= adjust;
s = peek;
}
break;
case '[':
- peek = is_timestamp(s);
+ peek = is_timestamp(s, *len);
if (!peek) {
break;
}
@@ -165,9 +192,16 @@ char *log_strtok_r(char *s, char **last) {
*last = s;
return tok;
}
+ adjust = peek - s;
+ if (adjust > *len) {
+ adjust = *len;
+ }
+ *sublen += adjust;
+ *len -= adjust;
s = peek;
break;
}
+ ++*sublen;
}
// NOTREACHED
}
@@ -214,13 +248,13 @@ bool LogKlog::onDataAvailable(SocketClient *cli) {
bool full = len == (sizeof(buffer) - 1);
char *ep = buffer + len;
*ep = '\0';
- len = 0;
+ size_t sublen;
for(char *ptr = NULL, *tok = buffer;
- ((tok = log_strtok_r(tok, &ptr)));
+ ((tok = log_strntok_r(tok, &len, &ptr, &sublen)));
tok = NULL) {
- if (((tok + strlen(tok)) == ep) && (retval != 0) && full) {
- len = strlen(tok);
- memmove(buffer, tok, len);
+ if (((tok + sublen) >= ep) && (retval != 0) && full) {
+ memmove(buffer, tok, sublen);
+ len = sublen;
break;
}
if (*tok) {
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index d1a248e..469affd 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -21,7 +21,7 @@
#include <log/log_read.h>
#include "LogReader.h"
-char *log_strtok_r(char *str, char **saveptr);
+char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen);
class LogKlog : public SocketListener {
LogBuffer *logbuf;
diff --git a/logd/main.cpp b/logd/main.cpp
index bb5d399..2ed52be 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -287,30 +287,31 @@ static void readDmesg(LogAudit *al, LogKlog *kl) {
return;
}
- int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
- if (len <= 0) {
+ int rc = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
+ if (rc <= 0) {
return;
}
- len += 1024; // Margin for additional input race or trailing nul
+ size_t len = rc + 1024; // Margin for additional input race or trailing nul
std::unique_ptr<char []> buf(new char[len]);
- int rc = klogctl(KLOG_READ_ALL, buf.get(), len);
+ rc = klogctl(KLOG_READ_ALL, buf.get(), len);
if (rc <= 0) {
return;
}
- if (rc < len) {
+ if ((size_t)rc < len) {
len = rc + 1;
}
- buf[len - 1] = '\0';
+ buf[--len] = '\0';
if (kl) {
kl->synchronize(buf.get(), len);
}
+ size_t sublen;
for (char *ptr = NULL, *tok = buf.get();
- (rc >= 0) && ((tok = log_strtok_r(tok, &ptr)));
+ (rc >= 0) && ((tok = log_strntok_r(tok, &len, &ptr, &sublen)));
tok = NULL) {
if (al) {
rc = al->log(tok, sublen);