Navigation Menu

Skip to content

Commit

Permalink
INI: Parse line with multiple = differently
Browse files Browse the repository at this point in the history
The new strategy is **far from ideal**, since it does not allow us to
save certain keys properly. Anyway, at least it should now be possibly
to save keys and values containing delimiter characters (`=`).

This commit closes ElektraInitiative#1721.
  • Loading branch information
sanssecours committed Feb 17, 2018
1 parent 5d0bc6b commit 98e6a06
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 69 deletions.
1 change: 1 addition & 0 deletions doc/news/_preparation_next_release.md
Expand Up @@ -192,6 +192,7 @@ Many problems were resolved with the following fixes:
- We fixed [internal inconsistency](https://github.com/ElektraInitiative/libelektra/pull/1761) in the CMake code of the [Augeas plugin](https://www.libelektra.org/plugins/augeas)
- We fixed various small bugs that could potentially cause the INI plugin to crash
- The INI plugin now [converts a section to a normal key-value pair](https://github.com/ElektraInitiative/libelektra/issues/1793) if you store a value inside it. This has the advantage that you will not [lose data unexpectedly anymore](https://github.com/ElektraInitiative/libelektra/issues/1697).
- The [INI plugin](https://www.libelektra.org/plugins/ini) should now read most key-value pairs containing separation characters (`=`) properly.
- We fixed the [haskell bindings and plugins on Debian Stretch](https://github.com/ElektraInitiative/libelektra/pull/1787)
and added a [new build server job](https://build.libelektra.org/job/elektra-haskell/) to test that in the future.

Expand Down
21 changes: 21 additions & 0 deletions src/plugins/ini/README.md
Expand Up @@ -297,3 +297,24 @@ kdb rm -r /examples/ini
sudo kdb umount /examples/ini
```

## Special Characters

The INI plugin also supports values and keys containing delimiter characters (`=`) properly.

```sh
sudo kdb mount test.ini user/examples/ini ini

printf '[section1]\n' > `kdb file user/examples/ini`
printf 'hello = world\n' >> `kdb file user/examples/ini`

kdb get user/examples/ini/section1/hello
#> world

kdb set user/examples/ini/section1/x=x 'a + b = b + a'
kdb get user/examples/ini/section1/x=x
#> a + b = b + a

# Undo modifications
kdb rm -r user/examples/ini
sudo kdb umount user/examples/ini
```
118 changes: 49 additions & 69 deletions src/plugins/ini/inih-r29/inih.c
Expand Up @@ -411,92 +411,72 @@ int ini_parse_file (FILE * file, const struct IniConfig * config, void * user)
else
{
ELEKTRA_LOG_DEBUG ("Found multiple delimiters");
ptr = start + 1;
while (*ptr && (*ptr != delim ||
(*(ptr + 1) != '"' && *(ptr + 2) != '"' && *(ptr - 1) != '"' && *(ptr - 2) != '"')))
{
++ptr;
}
if (*ptr)

end = start + 1;
if (*start == '"')
{
ELEKTRA_LOG_DEBUG ("Found double quote character around delimiter");
char tmpDel[4] = { ' ', delim, ' ', '\0' };
end = strstr (ptr, tmpDel);
name = NULL;
ELEKTRA_ASSERT (*ptr == delim, "Variable `*ptr` does not contain delimiter!");
if (end)
/* Quoted Name:
- The name has to end with a double quote
- We do not allow any double quotes inside the name
*/
name = start + 1;
while (*end && *end != '"')
{
// keyname == "=" or " = " where '=' is the delimiter
if (*(ptr + 1) == '"')
{
*(ptr + 1) = '\0';
}
else if (*(ptr + 2) == '"')
{
*(ptr + 2) = '\0';
}
if (*(ptr - 1) == '"')
*(ptr - 1) = '\0';
else if (*(ptr - 2) == '"')
*(ptr - 2) = '\0';
name = ptr;
end++;
}
else
if (!*end)
{
*ptr = '\0';
rstrip (start);
if (*start == '"') ++start;
if (*(ptr - 1) == '"')
*(ptr - 1) = '\0';
else if (*(ptr - 2) == '"')
*(ptr - 2) = '\0';
name = start;
error = lineno;
break;
}
value = ptr + 1;
*end = '\0';

end = find_char_or_comment (value, '\0');
if (*end == ';') *end = '\0';
rstrip (value);
if (*value == '"' || *(value + 1) == '"')
value = end + 1;
value = lskip (value);
if (!*value || *value != delim)
{
if (*value == '"')
*(value++) = '\0';
else if (*(value + 1) == '"')
{
*(value + 1) = '\0';
value += 2;
}
while ((*end != '"') && !isprint (*end) && end > value)
--end;
if (*end == '"') *end = '\0';
error = lineno;
break;
}
value++;
}
else
{
ELEKTRA_LOG_DEBUG ("Found no double quote character around delimiter");
rstrip (start);
/* Unquoted Name:
- The name can not contain a delimiter unless it is the very first character
- Trailing whitespace is removed from the name
*/
name = start;
end = strchr (start, delim);
while (*end && *end != delim)
{
end++;
}
if (!end)
{
ELEKTRA_LOG_DEBUG ("Found no delimiter");
value = NULL;
error = lineno;
break;
}
else
*end = '\0';
start = rstrip (start);
value = end + 1;
}
value = lskip (value);

end = find_char_or_comment (value, '\0');
if (*end == ';') *end = '\0';
rstrip (value);
if (*value == '"' || *(value + 1) == '"')
{
if (*value == '"')
*(value++) = '\0';
else if (*(value + 1) == '"')
{
ELEKTRA_LOG_DEBUG ("Found delimiter");
if (*end == delim) *end = '\0';
rstrip (end - 1);
value = lskip (end + 1);
rstrip (value);
if (*value == '"')
{
*(value++) = '\0';
while ((*end != '"') && !isprint (*end) && end > value)
--end;
if (*end == '"') *end = '\0';
}
*(value + 1) = '\0';
value += 2;
}
while ((*end != '"') && !isprint (*end) && end > value)
--end;
if (*end == '"') *end = '\0';
}
strncpy0 (prev_name, name, sizeof (prev_name));

Expand Down

0 comments on commit 98e6a06

Please sign in to comment.