From b648a112f2d2a01b2f7adb7b847ce1731601952d Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Mon, 15 Jun 2009 17:41:50 -0500 Subject: [PATCH] Improve string parsing code Currently next_string and next_hexstring functions use a static buffer in the iterator to store the value. This value is clobbered as soon as next_string or next_hexstring is called. Instead, we copy the entire line in iter_next and use it as a scratch buffer. The only limitation is that lines of max 2048 are possible, however these are limited to around this size by parts of the standard. --- gatchat/gatresult.c | 33 ++++++++++++++++++--------------- gatchat/gatresult.h | 4 +++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/gatchat/gatresult.c b/gatchat/gatresult.c index 8da88211..7a983083 100644 --- a/gatchat/gatresult.c +++ b/gatchat/gatresult.c @@ -43,13 +43,18 @@ gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix) { char *line; int prefix_len = prefix ? strlen(prefix) : 0; + int linelen; while ((iter->l = iter->l->next)) { line = iter->l->data; + linelen = strlen(line); + + if (linelen > G_AT_RESULT_LINE_LENGTH_MAX) + continue; if (prefix_len == 0) { iter->line_pos = 0; - return TRUE; + goto out; } if (g_str_has_prefix(line, prefix) == FALSE) @@ -61,10 +66,15 @@ gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix) line[iter->line_pos] == ' ') iter->line_pos += 1; - return TRUE; + goto out; } return FALSE; + +out: + /* Already checked the length to be no more than buflen */ + strcpy(iter->buf, line); + return TRUE; } const char *g_at_result_iter_raw_line(GAtResultIter *iter) @@ -116,7 +126,7 @@ gboolean g_at_result_iter_next_string(GAtResultIter *iter, const char **str) /* Omitted string */ if (line[pos] == ',') { end = pos; - memset(iter->buf, 0, sizeof(iter->buf)); + iter->buf[pos] = '\0'; goto out; } @@ -131,11 +141,7 @@ gboolean g_at_result_iter_next_string(GAtResultIter *iter, const char **str) if (line[end] != '"') return FALSE; - if (end - pos >= sizeof(iter->buf)) - return FALSE; - - strncpy(iter->buf, line+pos, end-pos); - memset(iter->buf + end - pos, 0, sizeof(iter->buf) - end + pos); + iter->buf[end] = '\0'; /* Skip " */ end += 1; @@ -144,7 +150,7 @@ out: iter->line_pos = skip_to_next_field(line, end, len); if (str) - *str = iter->buf; + *str = iter->buf + pos; return TRUE; } @@ -172,7 +178,7 @@ gboolean g_at_result_iter_next_hexstring(GAtResultIter *iter, /* Omitted string */ if (line[pos] == ',') { end = pos; - memset(iter->buf, 0, sizeof(iter->buf)); + iter->buf[pos] = '\0'; goto out; } @@ -184,19 +190,16 @@ gboolean g_at_result_iter_next_hexstring(GAtResultIter *iter, if ((end - pos) & 1) return FALSE; - if ((end - pos) / 2 >= sizeof(iter->buf)) - return FALSE; *length = (end - pos) / 2; - for (bufpos = iter->buf; pos < end; pos += 2) + for (bufpos = iter->buf + pos; pos < end; pos += 2) sscanf(line + pos, "%02hhx", bufpos++); - memset(bufpos, 0, sizeof(iter->buf) - (bufpos - iter->buf)); out: iter->line_pos = skip_to_next_field(line, end, len); if (str) - *str = (guint8 *) iter->buf; + *str = (guint8 *) bufpos - *length; return TRUE; } diff --git a/gatchat/gatresult.h b/gatchat/gatresult.h index cbe6d050..fc4c123c 100644 --- a/gatchat/gatresult.h +++ b/gatchat/gatresult.h @@ -33,10 +33,12 @@ struct _GAtResult { typedef struct _GAtResult GAtResult; +#define G_AT_RESULT_LINE_LENGTH_MAX 2048 + struct _GAtResultIter { GAtResult *result; GSList *l; - char buf[2048]; + char buf[G_AT_RESULT_LINE_LENGTH_MAX + 1]; unsigned int line_pos; GSList pre; };