diff options
author | Mark Salyzyn <salyzyn@google.com> | 2015-09-02 07:39:53 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-11-01 04:29:12 -0800 |
commit | c5a324fe084901a93215498f983703e483d9c000 (patch) | |
tree | 2de4fecf9739c88134280ffda3570fd34ab06c58 /logd | |
parent | 064c3a5ea2bdc8a0332f8d7d1c40f593c4b2ff1f (diff) | |
download | system_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.cpp | 82 | ||||
-rw-r--r-- | logd/LogKlog.h | 2 | ||||
-rw-r--r-- | logd/main.cpp | 15 |
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); |