summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2009-06-15 17:41:50 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-06-30 12:44:05 -0700
commitf633664e4164c882295779d85cf0b2da8c375406 (patch)
tree361a413583dfd312aed1a802d877aa7342ea15a2
parent726628df95cfbc82f5481d3123bd23e00376ea36 (diff)
downloadconnman-f633664e4164c882295779d85cf0b2da8c375406.tar.gz
connman-f633664e4164c882295779d85cf0b2da8c375406.tar.bz2
connman-f633664e4164c882295779d85cf0b2da8c375406.zip
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.
-rw-r--r--gatchat/gatresult.c33
-rw-r--r--gatchat/gatresult.h4
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;
};