Stephen Gallagher wrote:
Can we please come at this issue from the right direction? The reason
that this is even being debated is because we learned of another program
(certmonger) that is using INI files to store binary data.
THIS IS WRONG.
+1 This should simple be a pointer to a file containing the binary data.
Why is data being stored in an INI file?
This is not an appropriate use-case for the INI file format, and is
not
an example to follow. For storing binary data, there are plenty of more
sensible formats, such as yaml. In the particular case of certmonger, an
SQLite database or other small embedded DB would be a much better idea.
This is not my project, so it's not my concern.
We need to establish what the goals are for an INI file. In the vast
majority of cases (including the SSSD), they are used as a configuration
file for a program. Configuration files are expected to set
site-specific values for the execution of a program. Storage of data
should be relegated to a file format suitable for data storage.
So, it follows that for libini_CONFIG, we should only expect to
reasonably store configuration data. So here's my proposal for what we
should do:
1) First and foremost: as far as libini_config should be concerned, ALL
values should be treated as a single buffer. We should not offer to
handle escapes at all. This means that if the literal characters "\n"
appear in the string, they should be passed to the INI consumer as two
characters: a backslash followed by the letter n.
If the consumer of libini_config wishes to convert the string they got
back, it is up to them. We should only be in the business of returning
the exact contents of the value.
+1 We should be returning the exact contents and any escaping should be
up to what is reading and using the contents.
I believe we are trying to make this way to complicated. It is a simple
INI file.
IMHO
2) Leading whitespace should be ignored on all lines. This means
that
name = value
should result in the returned string "value" with no exceptions. If for
some reason the consumer of the interface needs leading whitespace, it
should be up to them to determine a reasonable way to denote this in
their source code.
They might decide to quote the whole string:
name = " value"
or they might decide to represent leading spaces with an escape of their
design:
name = %s%s%svalue
We would return these literal strings as
" value"
and
%s%s%svalue
respectively
3) Newlines should be handled as described in RFC822. In other words,
there need be no backslash escape denoting the end of the line. If the
libini_config parser detects a newline, it should check the first
character of the next line. If this character is a space or tab, the
parser should insert exactly one space in the resulting string.
name = value
continued value
continued value2
<tab>continued value3
Would be returned to the caller as:
value continued value continued value2 continued value3
If the caller wanted to ensure that there were actual newlines and/or
exact spaces, then they would be required to add their own escapes and
post-process the return from libini_config.
In conclusion: I think attempting to solve the newline/escape problem in
libini_config itself is both too complex and too limiting. It is more
complexity being added to the libini_config than a simple INI file
parser needs to have, and by implementing any particular approach to
managing the data, we are limiting is usability to only those use-cases
that we can come up with.
--
Jenny Galipeau <jgalipea(a)redhat.com>
Principal Software QA Engineer
Red Hat, Inc. Security Engineering
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/