[network-manager-openvpn/th/ovpn-import-bgo761285: 2/13] fixup! properties: add args_parse_line() function to parse lines in openvpn configuration files



commit 1c78afc174c448d671094fc389a354fa299a17d0
Author: Thomas Haller <thaller redhat com>
Date:   Wed Feb 3 11:55:26 2016 +0100

    fixup! properties: add args_parse_line() function to parse lines in openvpn configuration files

 properties/import-export.c |   49 +++++++++++++++++++++++++++++++------------
 1 files changed, 35 insertions(+), 14 deletions(-)
---
diff --git a/properties/import-export.c b/properties/import-export.c
index d1f8180..fab6fde 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -140,6 +140,19 @@ _ch_skip_over_leading_whitespace (const char **str, gsize *len)
                _ch_step_1 (str, len);
 }
 
+static void
+_strbuf_append_c (char **buf, gsize *len, char ch)
+{
+       nm_assert (buf);
+       nm_assert (len);
+
+       g_return_if_fail (*len > 0);
+
+       (*buf)[0] = ch;
+       (*len)--;
+       *buf = &(*buf)[1];
+}
+
 static gboolean
 args_parse_line (const char *line,
                  gsize line_len,
@@ -147,7 +160,9 @@ args_parse_line (const char *line,
                  char **out_error)
 {
        gs_unref_array GArray *index = NULL;
-       GString *str;
+       gs_free char *str_buf_orig = NULL;
+       char *str_buf;
+       gsize str_buf_len;
        gsize i;
        const char *line_start = line;
        char **data;
@@ -183,14 +198,21 @@ args_parse_line (const char *line,
                return TRUE;
        }
 
-       str = g_string_sized_new (line_len + 5);
+       /* the maximum required buffer is @line_len+1 characters. We don't produce
+        * *more* characters then given in the input (plus trailing '\0'). */
+       str_buf_len = line_len + 1;
+       str_buf_orig = g_malloc (str_buf_len);
+       str_buf = str_buf_orig;
+
        index = g_array_new (FALSE, FALSE, sizeof (gsize));
 
-       while (line_len > 0) {
+       do {
                char quote, ch0;
                gssize word_start = line - line_start;
+               gsize index_i;
 
-               g_array_append_val (index, str->len);
+               index_i = str_buf - str_buf_orig;
+               g_array_append_val (index, index_i);
 
                do {
                        switch ((ch0 = _ch_step_1 (&line, &line_len))) {
@@ -204,14 +226,13 @@ args_parse_line (const char *line,
                                                if (line_len <= 0)
                                                        break;
                                        }
-                                       g_string_append_c (str, _ch_step_1 (&line, &line_len));
+                                       _strbuf_append_c (&str_buf, &str_buf_len, _ch_step_1 (&line, 
&line_len));
                                }
 
                                if (line_len <= 0) {
                                        *out_error = g_strdup_printf (_("unterminated %s at position %lld"),
                                                                      quote == '"' ? _("double quote") : 
_("single quote"),
                                                                      (long long) word_start);
-                                       g_string_free (str, TRUE);
                                        return FALSE;
                                }
 
@@ -221,36 +242,36 @@ args_parse_line (const char *line,
                                if (line_len <= 0) {
                                        *out_error = g_strdup_printf (_("trailing escaping backslash at 
position %lld"),
                                                                      (long long) word_start);
-                                       g_string_free (str, TRUE);
                                        return FALSE;
                                }
-                               g_string_append_c (str, _ch_step_1 (&line, &line_len));
+                               _strbuf_append_c (&str_buf, &str_buf_len, _ch_step_1 (&line, &line_len));
                                break;
                        default:
                                if (g_ascii_isspace (ch0))
                                        goto word_completed;
-                               g_string_append_c (str, ch0);
+                               _strbuf_append_c (&str_buf, &str_buf_len, ch0);
                                break;
                        }
                } while (line_len > 0);
 word_completed:
 
                /* the current word is complete.*/
-               g_string_append_c (str, '\0');
+               _strbuf_append_c (&str_buf, &str_buf_len, '\0');
                _ch_skip_over_leading_whitespace (&line, &line_len);
-       }
+       } while (line_len > 0);
+
+       str_buf_len = str_buf - str_buf_orig;
 
        /* pack the result in a strv array */
-       data = g_malloc ((sizeof (const char *) * (index->len + 1)) + str->len);
+       data = g_malloc ((sizeof (const char *) * (index->len + 1)) + str_buf_len);
 
        pdata = (char *) &data[index->len + 1];
-       memcpy (pdata, str->str, str->len);
+       memcpy (pdata, str_buf_orig, str_buf_len);
 
        for (i = 0; i < index->len; i++)
                data[i] = &pdata[g_array_index (index, gsize, i)];
        data[i] = NULL;
 
-       g_string_free (str, TRUE);
        *out_p = (const char **) data;
 
        return TRUE;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]