No more posts about Jansson releases
Jansson 2.8 was released yesterday. Because of lack of time, I haven't written blog posts about changes after the 2.6 release, and I'm not planning to do so in the future, either.
Jansson 2.8 was released yesterday. Because of lack of time, I haven't written blog posts about changes after the 2.6 release, and I'm not planning to do so in the future, either.
Jansson 2.6 was released already on 2014-02-11, but I totally forgot to blog about it or even update Jansson's web page. Sorry about that!
Jansson 2.6 is mainly a security release, changing the hash function that is used by Jansson's hashtable implementation. Other changes include minor documentation and build system corrections. For a more comprehensive list of changes, see the release notes.
Jansson's old hash function was vulnerable to a denial of service attack. By using specially crafted keys, the attacker could reduce the performance of most object operations. For example, decoding a JSON text with such crafted keys would take tens of seconds for a relatively small file.
Jansson 2.6 changes the hash function to Bob Jenkins' lookup3, which
supports seeding. As no non-cryptographic hash function is
immune to the key crafting problem, the hash function is seeded by
random data when the first JSON object is created, either by
explicitly calling
json_object()
,
or by implicitly creating a new object e.g. by decoding a JSON text
or
calling json_pack()
.
The purpose of seeding is to make the hash function yield different results on each program run. This makes it virtually impossible to launch a DoS attack anymore.
The hardest part of seeding is how to actually generate random data
in a thread-safe manner. Jansson uses /dev/urandom
if
it's available, or CryptGenRandom()
on Windows. If
neither are available, a combination of a microsecond precision
timestamp and process ID are used as the seed. Seed generation is
guarded by architecture dependent lock-free operations to ensure
thread safety.
A new
function, json_object_seed()
,
is also exposed, to make it possible for the user to initiate the
seeding, e.g. before spawning any threads.
Jansson 2.5 was released a few days ago. It was almost a year since last release, and a lot has happened during this time. In this post, I'll sum up the most important new features. For a more comprehensive list of changes, see the release notes.
json_pack()
and friends learned new format
specifiers: s#
, +#
and +#
.
All of them deal with packing strings, and they work with both
object keys and string values.
The s#
format lets you define a length of a substring to
be packed. Example:
const char *data = "abcdef"; json_pack("{s#: s#", data, 3, data + 3, 3); /* ==> {"abd": "def"} */
The +
format makes it possible to concatenate strings
on the fly easily. It only works after a s
or
a +
, and has the effect of joining the given string to
the previous string:
json_pack("{s+: s++}", "abc", "def", "foo", "bar", "baz"); /* ==> {"abcdef": "foobarbaz"} */
And +#
is of course for concatenating a substring.
Here's a more complex example that shows that the new format
specifiers can be mixed in any way you can think of:
const char *data = "abcdef"; json_pack("{s+#+: s#+#", "fed", data, 3, data + 3, data, 1, data, 2); /* ==> {"fedabcdef": "aab"} */
The new format specifiers are a response for two types of user needs
that are discussed regularly
on GitHub
and mailing
list: Creating string values from non-NUL terminated buffers by
specifying a length, and making it easier to work with strings
directly in Jansson without having to do the C level plumbing
yourself. s#
solves the first need, and +
and +#
help with a common use case of concatenating two
strings, although they're definitely not a magic bullet for every
string manipulation need.
There's also a good reason why these operations were implemented as
an extension to json_pack()
and not API functions of
their own. Creating a new API function for every combination of
possible string operations, encoding control, allocation schemes,
etc. would need a vast amount of string functions. Extending all of
this to object keys would make the situation three times worse.
Support for CMake was perhaps the single most requested feature for a long time. While GNU Autotools, Jansson's default build system, generally works well on Unix-like platforms, many people find CMake generally better and easier to use. It also has better support for non-Unix systems, namely Windows.
GNU Autoconf, Automake and Libtool still stay the default build system for Jansson. However, the CMake build system is complete in a sense that it does everything that the autotools build system does (generates documentation, runs tests, etc.).
Many thanks to Paul Harris for initially developing the CMake support, and to Joakim Söderberg for finishing the work and correcting many bugs and feature requests afterwards.
A new decoding flag JSON_DECODE_INT_AS_REAL
was added.
It makes the decoder return all numbers as reals, regardless of
whether their text representation
contains .
, e
or E
.
json_array_foreach()
macro was added, paralleling
json_object_foreach()
.
Even though a loop over an array is easier to create, this macro
makes it even simpler and better looking to iterate over an array:
json_t *array; /* holds an array */ size_t index; json_t *value; json_array_foreach(array, index, value) { /* index is the current position of iteration, value is the JSON value at that position. */ }
The struct json_t
can now be forward declared. This
makes it possible to avoid including <jansson.h>
in header files that declare global json_t *
variables
or funtions whose signature uses json_t *
.
Jansson's documentation has been moved to Read the Docs, an amazing service for hosting Sphinx-powered documentation. The documentation of many popular open source projects are already hosted on RTD (e.g. pip, South, Tornado), and it seems to be quite popular especially among open source Python projects.
The main motivation for me to do this change was the mobile aware Sphinx theme. For a long time I've been aware of the the fact that Jansson's documentation cannot be viewed nicely with mobile devices, so it was about time to fix it. The docs look a bit different now, but I think it's a change for the better.
In addition to mobile support, I also got automatic documentation builds for all branches. It was as easy as pointing RTD to Jansson's git repo and selecting tags and branches that get built automatically. GitHub has a built-in service hook that rebuilds changed docs each time I push. Could it be easier than this?
I hope you like the new documentation as much as I do!
Jansson 2.4 has been released. This release adds new features and fixes a few bugs and documentation issues. It also adds support for building the library on Microsoft Visual Studio. The full release notes are available here.
A new macro, json_boolean(), was added. It returns either the JSON true or JSON false value based on its argument. It's useful in situations like this:
json_t *value; int yes = read_value_from_somewhere(); value = json_boolean(yes); /* false if yes == 0, true otherwise */
It's now possible to decode JSON with a callback providing the source JSON text. The new json_load_callback() function calls a callback repeatedly to read the source JSON. This is useful when the JSON data is received from a custom stream, for example.
JSON allows, but doesn't require, escaping /
characters
with \/
. This is useful when JSON is embedded in a
HTML <script>
tag, because the
string </
must not occur inside
a <script>
tag. When using the
new JSON_ESCAPE_SLASH
encoding flag, Jansson now
escapes /
's for you.
Until now, it has been possible to make Jansson produce invalid JSON
by creating a real value with an Inf or NaN special
value. json_real()
and json_real_set()
now check for these special values and refuse to accept them,
returning -1 to signal an error. (As a matter of
fact, json_real_set()
returned 0 even on other errors,
and this was fixed, too.)
It's now possible to build Jansson on Windows with Microsoft Visual
Studio. All the build errors have been fixed, and solution and
project files for Visual Studio 2010 are included in
the win32/vs2010/
directory in the source distribution.