<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/NetworkManager.git, branch th/strsplit-pt3</title>
<subtitle>gitlab.freedesktop.org: NetworkManager/NetworkManager.git
</subtitle>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/'/>
<entry>
<title>shared/tests: add unit tests for new flags of nm_utils_strsplit_set_full()</title>
<updated>2019-04-16T11:03:43+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-16T10:34:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=19dc43d0f8bbb2dba432cf5830e0ec071b37cd8a'/>
<id>19dc43d0f8bbb2dba432cf5830e0ec071b37cd8a</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>shared: remove unused nm_utils_str_simpletokens_extract_next()</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-12T10:51:17+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=9b5f33c2af837ab3a1e1535121e306716f5f41f9'/>
<id>9b5f33c2af837ab3a1e1535121e306716f5f41f9</id>
<content type='text'>
This can be replaced by nm_utils_escaped_tokens_split().

Note that nm_utils_escaped_tokens_split() does not behave exactly
the same. For example, nm_utils_str_simpletokens_extract_next() would
remove all backslashes and leave only the following character.
nm_utils_escaped_tokens_split() instead only strips backslashes
that preceed a delimiter, whitespace or another backslash.

But we should have one preferred way of tokenizing, and I find this
preferable, because it allows for most backslashes to appear verbatim.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This can be replaced by nm_utils_escaped_tokens_split().

Note that nm_utils_escaped_tokens_split() does not behave exactly
the same. For example, nm_utils_str_simpletokens_extract_next() would
remove all backslashes and leave only the following character.
nm_utils_escaped_tokens_split() instead only strips backslashes
that preceed a delimiter, whitespace or another backslash.

But we should have one preferred way of tokenizing, and I find this
preferable, because it allows for most backslashes to appear verbatim.
</pre>
</div>
</content>
</entry>
<entry>
<title>cli: use nm_utils_escaped_tokens_*() for handling policy routes</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-12T10:10:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=521e254ee7bfa09d44b94f25c36b044443b81323'/>
<id>521e254ee7bfa09d44b94f25c36b044443b81323</id>
<content type='text'>
Optimally, all list types properties in nmcli support proper escaping.
For that, we should use nm_utils_escaped_tokens_*() API.

For now, just change that for policy routes. They were just added recently,
so no change in behavior of released API.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Optimally, all list types properties in nmcli support proper escaping.
For that, we should use nm_utils_escaped_tokens_*() API.

For now, just change that for policy routes. They were just added recently,
so no change in behavior of released API.
</pre>
</div>
</content>
</entry>
<entry>
<title>libnm: use nm_utils_escaped_tokens_*() for parsing NMIPRoutingRule</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-12T10:38:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=0ea16fc4eab582a1148e709b918d3f5fc88bc03e'/>
<id>0ea16fc4eab582a1148e709b918d3f5fc88bc03e</id>
<content type='text'>
Replace nm_utils_str_simpletokens_extract_next() by
nm_utils_escaped_tokens_split().

nm_utils_escaped_tokens_split() should become our first choice for
parsing and tokenizing.

Note that both nm_utils_str_simpletokens_extract_next() and
nm_utils_escaped_tokens_split() need to strdup the string once,
and tokenizing takes O(n). So, they are roughtly the same performance
wise. The only difference is, that as we iterate through the tokens,
we might abort early on error with nm_utils_str_simpletokens_extract_next()
and not parse the entire string. But that is a small benefit, since we
anyway always strdup() the string (being O(n) already).

Note that to-string will no longer escape ',' and ';'. This is a change
in behavior, of unreleased API. Also note, that escaping these is no
longer necessary, because nmcli soon will also use nm_utils_escaped_tokens_*().

Another change in behavior is that nm_utils_str_simpletokens_extract_next()
treated invalid escape sequences (backslashes followed by an arbitrary
character), buy stripping the backslash. nm_utils_escaped_tokens_*()
leaves such backslashes as is, and only honors them if they are followed
by a whitespace (the delimiter) or another backslash. The disadvantage
of the new approach is that backslashes are treated differently
depending on the following character. The benefit is, that most
backslashes can now be written verbatim, not requiring them to escape
them with a double-backslash.

Yes, there is a problem with these nested escape schemes:

  - the caller may already need to escape backslash in shell.

  - then nmcli will use backslash escaping to split the rules at ','.

  - then nm_ip_routing_rule_from_string() will honor backslash escaping
    for spaces.

  - then iifname and oifname use backslash escaping for nm_utils_buf_utf8safe_escape()
    to express non-UTF-8 characters (because interface names are not
    necessarily UTF-8).

This is only redeamed because escaping is really only necessary for very
unusual cases, if you want to embed a backslash, a space, a comma, or a
non-UTF-8 character. But if you have to, now you will be able to express
that.

The other upside of these layers of escaping is that they become all
indendent from each other:

  - shell can accept quoted/escaped arguments and will unescape them.

  - nmcli can do the tokenizing for ',' (and escape the content
    unconditionally when converting to string).

  - nm_ip_routing_rule_from_string() can do its tokenizing without
    special consideration of utf8safe escaping.

  - NMIPRoutingRule takes iifname/oifname as-is and is not concerned
    about nm_utils_buf_utf8safe_escape(). However, before configuring
    the rule in kernel, this utf8safe escape will be unescaped to get
    the interface name (which is non-UTF8 binary).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Replace nm_utils_str_simpletokens_extract_next() by
nm_utils_escaped_tokens_split().

nm_utils_escaped_tokens_split() should become our first choice for
parsing and tokenizing.

Note that both nm_utils_str_simpletokens_extract_next() and
nm_utils_escaped_tokens_split() need to strdup the string once,
and tokenizing takes O(n). So, they are roughtly the same performance
wise. The only difference is, that as we iterate through the tokens,
we might abort early on error with nm_utils_str_simpletokens_extract_next()
and not parse the entire string. But that is a small benefit, since we
anyway always strdup() the string (being O(n) already).

Note that to-string will no longer escape ',' and ';'. This is a change
in behavior, of unreleased API. Also note, that escaping these is no
longer necessary, because nmcli soon will also use nm_utils_escaped_tokens_*().

Another change in behavior is that nm_utils_str_simpletokens_extract_next()
treated invalid escape sequences (backslashes followed by an arbitrary
character), buy stripping the backslash. nm_utils_escaped_tokens_*()
leaves such backslashes as is, and only honors them if they are followed
by a whitespace (the delimiter) or another backslash. The disadvantage
of the new approach is that backslashes are treated differently
depending on the following character. The benefit is, that most
backslashes can now be written verbatim, not requiring them to escape
them with a double-backslash.

Yes, there is a problem with these nested escape schemes:

  - the caller may already need to escape backslash in shell.

  - then nmcli will use backslash escaping to split the rules at ','.

  - then nm_ip_routing_rule_from_string() will honor backslash escaping
    for spaces.

  - then iifname and oifname use backslash escaping for nm_utils_buf_utf8safe_escape()
    to express non-UTF-8 characters (because interface names are not
    necessarily UTF-8).

This is only redeamed because escaping is really only necessary for very
unusual cases, if you want to embed a backslash, a space, a comma, or a
non-UTF-8 character. But if you have to, now you will be able to express
that.

The other upside of these layers of escaping is that they become all
indendent from each other:

  - shell can accept quoted/escaped arguments and will unescape them.

  - nmcli can do the tokenizing for ',' (and escape the content
    unconditionally when converting to string).

  - nm_ip_routing_rule_from_string() can do its tokenizing without
    special consideration of utf8safe escaping.

  - NMIPRoutingRule takes iifname/oifname as-is and is not concerned
    about nm_utils_buf_utf8safe_escape(). However, before configuring
    the rule in kernel, this utf8safe escape will be unescaped to get
    the interface name (which is non-UTF8 binary).
</pre>
</div>
</content>
</entry>
<entry>
<title>cli: add new style for tokenizing/concatenating list options in nmcli</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-12T10:00:48+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=4c009c096bee1c21bc8fba906f4faf761fe6ffbe'/>
<id>4c009c096bee1c21bc8fba906f4faf761fe6ffbe</id>
<content type='text'>
nmcli supports list options (optlist and multilist properties).
These commonly are individual items, concatenated by a delimiter.

It should be generally possibly to express every value. That means, we
need some for of escaping mechanism for delimiters.

Currently this is all inconsistent or no escaping is supported. I intend
to fix that (which will be a change in behavior).

For now, just add yet another style of tokenzing/concatenating list
items in nmcli. This is the style to replace all other styles.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
nmcli supports list options (optlist and multilist properties).
These commonly are individual items, concatenated by a delimiter.

It should be generally possibly to express every value. That means, we
need some for of escaping mechanism for delimiters.

Currently this is all inconsistent or no escaping is supported. I intend
to fix that (which will be a change in behavior).

For now, just add yet another style of tokenzing/concatenating list
items in nmcli. This is the style to replace all other styles.
</pre>
</div>
</content>
</entry>
<entry>
<title>shared: add nm_utils_escaped_tokens_escape()</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-11T19:20:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=df8ef711771f15bfafcc98fc81e49e1a79342a2c'/>
<id>df8ef711771f15bfafcc98fc81e49e1a79342a2c</id>
<content type='text'>
This escapes strings so that they can be concatenated with a delimiter
and without loss tokenized with nm_utils_escaped_tokens_split().

Note that this is similar to _nm_utils_escape_plain() and
_nm_utils_escape_spaces(). The difference is that
nm_utils_escaped_tokens_escape() also escapes the last trailing
whitespace. That means, if delimiters contains all NM_ASCII_SPACES, then
it is identical to _nm_utils_escape_spaces(). Otherwise, the trailing
space is treated specially. That is, because
nm_utils_escaped_tokens_split() uses NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP,
to strip leading and trailing whitespace. To still express a trailing
whitespace, the last whitespace must be escaped. Note that
NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP also honors escaping any whitespace
(not only at the last position), but when escaping we don't need to
escape them, because unescaped (non-trailing) whitespace are taken just
fine.

The pair nm_utils_escaped_tokens_split() and
nm_utils_escaped_tokens_escape() are proposed as default way of
tokenizing a list of items. For example, with

  $ nmcli connection modify "$PROFILE" +ipv4.routing-rules 'priority 5 from 192.168.7.5/32 table 5, priority 6 iif a\, from 192.168.7.5/32 table 6'

Here we implement a to/from string function to handle one item
(nm_ip_routing_rule_{from,to}_string()). When such elements are combined with ',',
then we need to support an additional layer of escaping on top of that.
The advantage is that the indvidual to/from string functions are agnostic
to this second layer of escaping/tokenizing that nmcli employs to handle
a list of these items.
The disadvantage is that we possibly get multiple layers of backslash
escapings. That is only mitigated by the fact that nm_utils_escaped_tokens_*()
supports a syntax for which *most* characters don't need any special escaping.
Only delimiters, backslash, and the trailing space needs escaping, and
these are cases are expected to be few.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This escapes strings so that they can be concatenated with a delimiter
and without loss tokenized with nm_utils_escaped_tokens_split().

Note that this is similar to _nm_utils_escape_plain() and
_nm_utils_escape_spaces(). The difference is that
nm_utils_escaped_tokens_escape() also escapes the last trailing
whitespace. That means, if delimiters contains all NM_ASCII_SPACES, then
it is identical to _nm_utils_escape_spaces(). Otherwise, the trailing
space is treated specially. That is, because
nm_utils_escaped_tokens_split() uses NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP,
to strip leading and trailing whitespace. To still express a trailing
whitespace, the last whitespace must be escaped. Note that
NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP also honors escaping any whitespace
(not only at the last position), but when escaping we don't need to
escape them, because unescaped (non-trailing) whitespace are taken just
fine.

The pair nm_utils_escaped_tokens_split() and
nm_utils_escaped_tokens_escape() are proposed as default way of
tokenizing a list of items. For example, with

  $ nmcli connection modify "$PROFILE" +ipv4.routing-rules 'priority 5 from 192.168.7.5/32 table 5, priority 6 iif a\, from 192.168.7.5/32 table 6'

Here we implement a to/from string function to handle one item
(nm_ip_routing_rule_{from,to}_string()). When such elements are combined with ',',
then we need to support an additional layer of escaping on top of that.
The advantage is that the indvidual to/from string functions are agnostic
to this second layer of escaping/tokenizing that nmcli employs to handle
a list of these items.
The disadvantage is that we possibly get multiple layers of backslash
escapings. That is only mitigated by the fact that nm_utils_escaped_tokens_*()
supports a syntax for which *most* characters don't need any special escaping.
Only delimiters, backslash, and the trailing space needs escaping, and
these are cases are expected to be few.
</pre>
</div>
</content>
</entry>
<entry>
<title>shared: add NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED to nm_utils_strsplit_set_full()</title>
<updated>2019-04-16T10:57:55+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-11T17:24:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=354ebb1356aabbaf5873fd61bc2eb561b1f89e2d'/>
<id>354ebb1356aabbaf5873fd61bc2eb561b1f89e2d</id>
<content type='text'>
Add a new flag that will remove escape characters after splitting
the string.

This implements a special kind of backslash escaping. It's not C escape
sequences (like '\n' or '\020'), but simply to take the special character
following the backslash verbatim. Note that the backslash is only
considered special, if it's followed by a delimiter, another backslash,
or a whitespace (in combination with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP).

The main purpose of this form of escaping is nmcli's list options, like

  $ nmcli connection modify "$PROFILE" +ipv4.routing-rules 'priority 5 from 192.168.7.5/32 table 5, priority 6 iif a\, from 192.168.7.5/32 table 6'

It's a contrieved example, but the list options are a list of IP
addresses, rules, etc. They implement their own syntax for one element,
and are concatenated by ','. To support that one element may have
arbitrary characters (including the delimiter and whitespaces), nmcli
employs a tokenization with this special kind of escaping.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add a new flag that will remove escape characters after splitting
the string.

This implements a special kind of backslash escaping. It's not C escape
sequences (like '\n' or '\020'), but simply to take the special character
following the backslash verbatim. Note that the backslash is only
considered special, if it's followed by a delimiter, another backslash,
or a whitespace (in combination with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP).

The main purpose of this form of escaping is nmcli's list options, like

  $ nmcli connection modify "$PROFILE" +ipv4.routing-rules 'priority 5 from 192.168.7.5/32 table 5, priority 6 iif a\, from 192.168.7.5/32 table 6'

It's a contrieved example, but the list options are a list of IP
addresses, rules, etc. They implement their own syntax for one element,
and are concatenated by ','. To support that one element may have
arbitrary characters (including the delimiter and whitespaces), nmcli
employs a tokenization with this special kind of escaping.
</pre>
</div>
</content>
</entry>
<entry>
<title>shared: add NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP to nm_utils_strsplit_set_full()</title>
<updated>2019-04-16T09:38:21+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-11T11:32:43+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=ba25c3644a99916c0f84dd1a784ab4ff6b4b3745'/>
<id>ba25c3644a99916c0f84dd1a784ab4ff6b4b3745</id>
<content type='text'>
This will essentially call g_strstrip() on each token.

There are some specialties:

 - if the resulting word is empty after stripping, then according to
   %NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, the empty token will be
   removed. If that results in an emptry string array, %NULL will be
   returned.

 - if %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING is set, then
   whitespace that is backslash escaped is not removed.

Since this is a post-operation that happens after tokeninzing, it
could be done as a separate function. And we already have this function:
_nm_utils_unescape_plain() and _nm_utils_unescape_spaces().
However, that is ugly for several reasons:

 - the stripping should be part of the tokenizing, you shouldn't need
   several steps.

 - nm_utils_strsplit_set_full() returns a "const char **" which
   indicates the strings must not be freed. However, it is perfectly
   valid to modify the string inplace. Hence, the post-op function
   would need to cast the strings to "char *", which seems ugly
   (although we do that on many places, and it's guaranteed to work).

 - _nm_utils_unescape_plain()/_nm_utils_unescape_spaces() is indeed
   already used together with nm_utils_strsplit_set_full(). However,
   it requires to initialize the cb_lookup buffer again. I would expect
   that initializing the cb_lookup buffer is a large portion of what
   the function does already.
   This issue will be solved in the next commit by adding yet another flag
   which allows to unescape.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This will essentially call g_strstrip() on each token.

There are some specialties:

 - if the resulting word is empty after stripping, then according to
   %NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, the empty token will be
   removed. If that results in an emptry string array, %NULL will be
   returned.

 - if %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING is set, then
   whitespace that is backslash escaped is not removed.

Since this is a post-operation that happens after tokeninzing, it
could be done as a separate function. And we already have this function:
_nm_utils_unescape_plain() and _nm_utils_unescape_spaces().
However, that is ugly for several reasons:

 - the stripping should be part of the tokenizing, you shouldn't need
   several steps.

 - nm_utils_strsplit_set_full() returns a "const char **" which
   indicates the strings must not be freed. However, it is perfectly
   valid to modify the string inplace. Hence, the post-op function
   would need to cast the strings to "char *", which seems ugly
   (although we do that on many places, and it's guaranteed to work).

 - _nm_utils_unescape_plain()/_nm_utils_unescape_spaces() is indeed
   already used together with nm_utils_strsplit_set_full(). However,
   it requires to initialize the cb_lookup buffer again. I would expect
   that initializing the cb_lookup buffer is a large portion of what
   the function does already.
   This issue will be solved in the next commit by adding yet another flag
   which allows to unescape.
</pre>
</div>
</content>
</entry>
<entry>
<title>cli: avoid duplicate delimiters when printing objlist property</title>
<updated>2019-04-16T09:31:54+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-12T11:21:47+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=4fa0c07f0f53b7717344ab118d4b81a658dd0ada'/>
<id>4fa0c07f0f53b7717344ab118d4b81a658dd0ada</id>
<content type='text'>
Usually, obj_to_str_fcn() should not fail and always add something.
If not, remove the delimiter again.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Usually, obj_to_str_fcn() should not fail and always add something.
If not, remove the delimiter again.
</pre>
</div>
</content>
</entry>
<entry>
<title>cli: merge branch 'th/cli-select-connection'</title>
<updated>2019-04-16T07:16:14+00:00</updated>
<author>
<name>Thomas Haller</name>
<email>thaller@redhat.com</email>
</author>
<published>2019-04-16T07:16:14+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/NetworkManager.git/commit/?id=87c2b0e6cd686e33ec275761d0e81be374d204c3'/>
<id>87c2b0e6cd686e33ec275761d0e81be374d204c3</id>
<content type='text'>
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/108
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/108
</pre>
</div>
</content>
</entry>
</feed>
