digip.org blog

Jansson 2.6 released

By Petri Lehtinen on 2014-04-01

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.

New hash function

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 released

By Petri Lehtinen on 2013-09-23

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.

New format specifiers

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.

CMake build system

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.

Smaller features

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 moved to Read the Docs

By Petri Lehtinen on 2013-08-21

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 released

By Petri Lehtinen on 2012-09-23

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.

New features

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.

Bug fixes

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.)

Windows support

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.