[network-manager-openvpn/th/tmp] properties: fix parsing during import for openvpn special handling of comments and quoting
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/th/tmp] properties: fix parsing during import for openvpn special handling of comments and quoting
- Date: Mon, 27 Jun 2016 15:00:15 +0000 (UTC)
commit 36d175510d3be707d78778d62fdda1757dbc6ec1
Author: Thomas Haller <thaller redhat com>
Date: Mon Jun 27 16:14:18 2016 +0200
properties: fix parsing during import for openvpn special handling of comments and quoting
openvpn doesn't treat quotes and comments like shell does. Instead:
- quotes start with ';' or '#' and can start also not at the first
charater of the line. Comments can start at every beginning of a
word (but not inside a word). E.g. "a#comment" is not taken as "a"
followed by a comment, instead it is taken literally.
- quotation is quite peculiar. On the first character of a word,
openvpn decides whether it has a quoted word at hand or not.
In case of a quoted word, the word ends with the closing quote.
That means, "'a'b" becomes "a","b", not "ab".
In case of a unquoted word, quotes inside the word are ignored
until the word ends with spaces. That means, "a'b'" becomes
"a'b'".
See:
https://github.com/OpenVPN/openvpn/blob/2011b8324feca30df753a4a0a116d37c04742520/src/openvpn/options.c#L3639
properties/import-export.c | 87 +++++++++++++++++++--------------
properties/tests/conf/password.conf | 2 +-
properties/tests/test-import-export.c | 6 +-
3 files changed, 55 insertions(+), 40 deletions(-)
---
diff --git a/properties/import-export.c b/properties/import-export.c
index a558867..62d5f74 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -459,7 +459,7 @@ args_parse_line (const char *line,
index = g_array_new (FALSE, FALSE, sizeof (gsize));
- do {
+ for (;;) {
char quote, ch0;
gssize word_start = line - line_start;
gsize index_i;
@@ -467,51 +467,66 @@ args_parse_line (const char *line,
index_i = str_buf - str_buf_orig;
g_array_append_val (index, index_i);
- do {
- switch ((ch0 = _ch_step_1 (&line, &line_len))) {
- case '"':
- case '\'':
- quote = ch0;
-
- while (line_len > 0 && line[0] != quote) {
- if (quote == '"' && line[0] == '\\') {
- _ch_step_1 (&line, &line_len);
- if (line_len <= 0)
- break;
- }
- _strbuf_append_c (&str_buf, &str_buf_len, _ch_step_1 (&line,
&line_len));
- }
+ switch ((ch0 = _ch_step_1 (&line, &line_len))) {
+ case '"':
+ case '\'':
+ quote = ch0;
- if (line_len <= 0) {
- *out_error = g_strdup_printf (_("unterminated %s at position %lld"),
- quote == '"' ? _("double quote") :
_("single quote"),
- (long long) word_start);
- return FALSE;
+ while (line_len > 0 && line[0] != quote) {
+ if (quote == '"' && line[0] == '\\') {
+ _ch_step_1 (&line, &line_len);
+ if (line_len <= 0)
+ break;
}
+ _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);
+ return FALSE;
+ }
- _ch_step_1 (&line, &line_len);
- break;
- case '\\':
- if (line_len <= 0) {
- *out_error = g_strdup_printf (_("trailing escaping backslash at
position %lld"),
- (long long) word_start);
- return FALSE;
+ /* openvpn terminates parsing of quoted paramaters after the closing quote.
+ * E.g. "'a'b" gives "a", "b". */
+ _ch_step_1 (&line, &line_len);
+ break;
+ default:
+ /* once openvpn encounters a non-quoted word, it doesn't consider quoting
+ * inside the word.
+ * E.g. "a'b'" gives "a'b'". */
+ for (;;) {
+ if (ch0 == '\\') {
+ if (line_len <= 0) {
+ *out_error = g_strdup_printf (_("trailing escaping backslash
at position %lld"),
+ (long long) word_start);
+ return FALSE;
+ }
+ ch0 = _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;
_strbuf_append_c (&str_buf, &str_buf_len, ch0);
- break;
+ if (line_len <= 0)
+ break;
+ ch0 = _ch_step_1 (&line, &line_len);
+ if (g_ascii_isspace (ch0))
+ break;
}
- } while (line_len > 0);
-word_completed:
+ break;
+ }
/* the current word is complete.*/
_strbuf_append_c (&str_buf, &str_buf_len, '\0');
_ch_skip_over_leading_whitespace (&line, &line_len);
- } while (line_len > 0);
+
+ if (line_len <= 0)
+ break;
+
+ if (NM_IN_SET (line[0], ';', '#')) {
+ /* comments are allowed to start at the beginning of the next word. */
+ break;
+ }
+ }
str_buf_len = str_buf - str_buf_orig;
diff --git a/properties/tests/conf/password.conf b/properties/tests/conf/password.conf
index c924a4f..cfe5835 100644
--- a/properties/tests/conf/password.conf
+++ b/properties/tests/conf/password.conf
@@ -14,7 +14,7 @@ group openvpn
ca cacert.pem
-cipher AES-256-CBC
+cipher AES-256-CBC #xcomment
reneg-sec 0
auth-user-pass
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
index 936662c..a78d2d2 100644
--- a/properties/tests/test-import-export.c
+++ b/properties/tests/test-import-export.c
@@ -1287,9 +1287,9 @@ test_args_parse_line (void)
do_test_args_parse_line (" b \\ \\a ", TRUE, "b", " a");
do_test_args_parse_line ("\\ b \\ \\a ", TRUE, " b", " a");
do_test_args_parse_line ("'\\ b \\ \\a '", TRUE, "\\ b \\ \\a ");
- do_test_args_parse_line ("\"\\ b \\ \\a \"a'b'", TRUE, " b a ab");
- do_test_args_parse_line ("\"\\ b \\ \\a \"a\\ 'b'", TRUE, " b a a b");
- do_test_args_parse_line ("\"\\ b \\ \\a \"a\\ 'b' sd\\ \t", TRUE, " b a a b", "sd ");
+ do_test_args_parse_line ("\"\\ b \\ \\a \"a'b'", TRUE, " b a ", "a'b'");
+ do_test_args_parse_line ("\"\\ b \\ \\a \"a\\ 'b'", TRUE, " b a ", "a 'b'");
+ do_test_args_parse_line ("\"\\ b \\ \\a \"a\\ 'b' sd\\ \t", TRUE, " b a ", "a 'b'", "sd ");
do_test_args_parse_line ("\"adfdaf adf ", FALSE);
do_test_args_parse_line ("\"adfdaf adf \\\"", FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]