diff options
author | Petri Lehtinen <petri@digip.org> | 2010-03-28 21:44:41 +0300 |
---|---|---|
committer | Petri Lehtinen <petri@digip.org> | 2010-03-28 21:44:41 +0300 |
commit | 4e63fcd55d874485071073f181dbfc5b9e196600 (patch) | |
tree | 8c1aa0262a7ee2cdd6cc5c56b06b76660fd2d45e | |
parent | 49880cbabeb597a9c748a3d5f37e9961a084dce3 (diff) | |
parent | 024106bbfbd7376656876aa8bd00a333d5ada10c (diff) | |
download | jansson-4e63fcd55d874485071073f181dbfc5b9e196600.zip jansson-4e63fcd55d874485071073f181dbfc5b9e196600.tar.gz jansson-4e63fcd55d874485071073f181dbfc5b9e196600.tar.bz2 |
Merge branch '1.2'
Conflicts:
configure.ac
26 files changed, 147 insertions, 23 deletions
@@ -24,3 +24,4 @@ missing stamp-h1 *.pyc *.pc +/src/jansson.h diff --git a/configure.ac b/configure.ac index 6d21268..9a4bd99 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_PREREQ([2.59]) +AC_PREREQ([2.60]) AC_INIT([jansson], [1.2+], [petri@digip.org]) AM_INIT_AUTOMAKE([1.10 foreign]) @@ -18,6 +18,14 @@ AC_PROG_LIBTOOL # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_INT32_T +AC_C_INLINE +case $ac_cv_c_inline in + yes) json_inline=inline;; + no) json_inline=;; + *) json_inline=$ac_cv_c_inline;; +esac +AC_SUBST([json_inline]) + # Checks for library functions. AC_CONFIG_FILES([ @@ -25,6 +33,7 @@ AC_CONFIG_FILES([ Makefile doc/Makefile src/Makefile + src/jansson.h test/Makefile test/bin/Makefile test/suites/Makefile diff --git a/doc/conformance.rst b/doc/conformance.rst new file mode 100644 index 0000000..785a94d --- /dev/null +++ b/doc/conformance.rst @@ -0,0 +1,102 @@ +*************** +RFC Conformance +*************** + +JSON is specified in :rfc:`4627`, *"The application/json Media Type +for JavaScript Object Notation (JSON)"*. This chapter discusses +Jansson's conformance to this specification. + +Character Encoding +================== + +Jansson only supports UTF-8 encoded JSON texts. It does not support or +auto-detect any of the other encodings mentioned in the RFC, namely +UTF-16LE, UTF-16BE, UTF-32LE or UTF-32BE. Pure ASCII is supported, as +it's a subset of UTF-8. + +Strings +======= + +JSON strings are mapped to C-style null-terminated character arrays, +and UTF-8 encoding is used internally. Strings may not contain +embedded null characters, not even escaped ones. + +For example, trying to decode the following JSON text leads to a parse +error:: + + ["this string contains the null character: \u0000"] + +All other Unicode codepoints U+0001 through U+10FFFF are allowed. + +Numbers +======= + +Real vs. Integer +---------------- + +JSON makes no distinction between real and integer numbers; Jansson +does. Real numbers are mapped to the ``double`` type and integers to +the ``int`` type. + +A JSON number is considered to be a real number if its lexical +representation includes one of ``e``, ``E``, or ``.``; regardless if +its actual numeric value is a true integer (e.g., all of ``1E6``, +``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but +will be treated as real values). + +All other JSON numbers are considered integers. + +When encoding to JSON, real values are always represented +with a fractional part; e.g., the ``double`` value 3.0 will be +represented in JSON as ``3.0``, not ``3``. + +Overflow, Underflow & Precision +------------------------------- + +Real numbers whose absolute values are too small to be represented in +a C double will be silently estimated with 0.0. Thus, depending on +platform, JSON numbers very close to zero such as 1E-999 may result in +0.0. + +Real numbers whose absolute values are too large to be represented in +a C ``double`` type will result in an overflow error (a JSON decoding +error). Thus, depending on platform, JSON numbers like 1E+999 or +-1E+999 may result in a parsing error. + +Likewise, integer numbers whose absolute values are too large to be +represented in the ``int`` type will result in an overflow error (a +JSON decoding error). Thus, depending on platform, JSON numbers like +1000000000000000 may result in parsing error. + +Parsing JSON real numbers may result in a loss of precision. As long +as overflow does not occur (i.e. a total loss of precision), the +rounded approximate value is silently used. Thus the JSON number +1.000000000000000005 may, depending on platform, result in the +``double`` value 1.0. + +Signed zeros +------------ + +JSON makes no statement about what a number means; however Javascript +(ECMAscript) does state that +0.0 and -0.0 must be treated as being +distinct values, i.e. -0.0 |not-equal| 0.0. Jansson relies on the +underlying floating point library in the C environment in which it is +compiled. Therefore it is platform-dependent whether 0.0 and -0.0 will +be distinct values. Most platforms that use the IEEE 754 +floating-point standard will support signed zeros. + +Note that this only applies to floating-point; neither JSON, C, or +IEEE support the concept of signed integer zeros. + +.. |not-equal| unicode:: U+2260 + +Types +----- + +No support is provided in Jansson for any C numeric types other than +``int`` and ``double``. This excludes things such as unsigned types, +``long``, ``long long``, ``long double``, etc. Obviously, shorter +types like ``short`` and ``float`` are implicitly handled via the +ordinary C type coercion rules (subject to overflow semantics). Also, +no support or hooks are provided for any supplemental "bignum" type +add-on packages. diff --git a/doc/index.rst b/doc/index.rst index d6018b9..c7321df 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -34,6 +34,7 @@ Contents gettingstarted tutorial + conformance apiref changes diff --git a/src/hashtable.c b/src/hashtable.c index 4b58b26..a312047 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -5,6 +5,8 @@ * it under the terms of the MIT license. See LICENSE for details. */ +#include <config.h> + #include <stdlib.h> #include "hashtable.h" diff --git a/src/jansson.h b/src/jansson.h.in index 24b4949..4980d01 100644 --- a/src/jansson.h +++ b/src/jansson.h.in @@ -10,7 +10,10 @@ #include <stdio.h> -#ifdef __cplusplus +#ifndef __cplusplus +#define JSON_INLINE @json_inline@ +#else +#define JSON_INLINE inline extern "C" { #endif @@ -56,7 +59,8 @@ json_t *json_true(void); json_t *json_false(void); json_t *json_null(void); -static inline json_t *json_incref(json_t *json) +static JSON_INLINE +json_t *json_incref(json_t *json) { if(json && json->refcount != (unsigned int)-1) ++json->refcount; @@ -66,7 +70,8 @@ static inline json_t *json_incref(json_t *json) /* do not call json_delete directly */ void json_delete(json_t *json); -static inline void json_decref(json_t *json) +static JSON_INLINE +void json_decref(json_t *json) { if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0) json_delete(json); @@ -89,13 +94,13 @@ const char *json_object_iter_key(void *iter); json_t *json_object_iter_value(void *iter); int json_object_iter_set_new(json_t *object, void *iter, json_t *value); -static inline +static JSON_INLINE int json_object_set(json_t *object, const char *key, json_t *value) { return json_object_set_new(object, key, json_incref(value)); } -static inline +static JSON_INLINE int json_object_set_nocheck(json_t *object, const char *key, json_t *value) { return json_object_set_new_nocheck(object, key, json_incref(value)); @@ -116,19 +121,19 @@ int json_array_remove(json_t *array, unsigned int index); int json_array_clear(json_t *array); int json_array_extend(json_t *array, json_t *other); -static inline +static JSON_INLINE int json_array_set(json_t *array, unsigned int index, json_t *value) { return json_array_set_new(array, index, json_incref(value)); } -static inline +static JSON_INLINE int json_array_append(json_t *array, json_t *value) { return json_array_append_new(array, json_incref(value)); } -static inline +static JSON_INLINE int json_array_insert(json_t *array, unsigned int index, json_t *value) { return json_array_insert_new(array, index, json_incref(value)); @@ -483,14 +483,7 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error) value = strtod(saved_text, &end); assert(end == saved_text + lex->saved_text.length); - if(value == 0 && errno == ERANGE) { - error_set(error, lex, "real number underflow"); - goto out; - } - - /* Cannot test for +/-HUGE_VAL because the HUGE_VAL constant is - only defined in C99 mode. So let's trust in sole errno. */ - else if(errno == ERANGE) { + if(errno == ERANGE && value != 0) { error_set(error, lex, "real number overflow"); goto out; } diff --git a/src/value.c b/src/value.c index 7c41c89..e024fdb 100644 --- a/src/value.c +++ b/src/value.c @@ -6,6 +6,9 @@ */ #define _GNU_SOURCE + +#include <config.h> + #include <stdlib.h> #include <string.h> diff --git a/test/suites/invalid-strip/escaped-null-byte-in-string/error b/test/suites/invalid-strip/escaped-null-byte-in-string/error new file mode 100644 index 0000000..0fa36e2 --- /dev/null +++ b/test/suites/invalid-strip/escaped-null-byte-in-string/error @@ -0,0 +1,2 @@ +1 +\u0000 is not allowed diff --git a/test/suites/invalid-strip/escaped-null-byte-in-string/input b/test/suites/invalid-strip/escaped-null-byte-in-string/input new file mode 100644 index 0000000..60f7f7b --- /dev/null +++ b/test/suites/invalid-strip/escaped-null-byte-in-string/input @@ -0,0 +1 @@ +["\u0000 (null byte not allowed)"]
\ No newline at end of file diff --git a/test/suites/invalid-strip/null-byte-in-string/error b/test/suites/invalid-strip/null-byte-in-string/error index 0fa36e2..273f6d1 100644 --- a/test/suites/invalid-strip/null-byte-in-string/error +++ b/test/suites/invalid-strip/null-byte-in-string/error @@ -1,2 +1,2 @@ 1 -\u0000 is not allowed +control character 0x0 near '"null byte ' diff --git a/test/suites/invalid-strip/null-byte-in-string/input b/test/suites/invalid-strip/null-byte-in-string/input Binary files differindex 60f7f7b..c0d82be 100644 --- a/test/suites/invalid-strip/null-byte-in-string/input +++ b/test/suites/invalid-strip/null-byte-in-string/input diff --git a/test/suites/invalid-strip/null-byte-outside-string/error b/test/suites/invalid-strip/null-byte-outside-string/error new file mode 100644 index 0000000..f0e68ec --- /dev/null +++ b/test/suites/invalid-strip/null-byte-outside-string/error @@ -0,0 +1,2 @@ +1 +invalid token near end of file diff --git a/test/suites/invalid-strip/null-byte-outside-string/input b/test/suites/invalid-strip/null-byte-outside-string/input Binary files differnew file mode 100644 index 0000000..75447d8 --- /dev/null +++ b/test/suites/invalid-strip/null-byte-outside-string/input diff --git a/test/suites/invalid-strip/real-underflow/error b/test/suites/invalid-strip/real-underflow/error deleted file mode 100644 index 1b65d40..0000000 --- a/test/suites/invalid-strip/real-underflow/error +++ /dev/null @@ -1,2 +0,0 @@ -1 -real number underflow near '123e-10000000' diff --git a/test/suites/invalid/escaped-null-byte-in-string/error b/test/suites/invalid/escaped-null-byte-in-string/error new file mode 100644 index 0000000..0fa36e2 --- /dev/null +++ b/test/suites/invalid/escaped-null-byte-in-string/error @@ -0,0 +1,2 @@ +1 +\u0000 is not allowed diff --git a/test/suites/invalid/escaped-null-byte-in-string/input b/test/suites/invalid/escaped-null-byte-in-string/input new file mode 100644 index 0000000..22ae82b --- /dev/null +++ b/test/suites/invalid/escaped-null-byte-in-string/input @@ -0,0 +1 @@ +["\u0000 (null byte not allowed)"] diff --git a/test/suites/invalid/null-byte-in-string/error b/test/suites/invalid/null-byte-in-string/error index 0fa36e2..273f6d1 100644 --- a/test/suites/invalid/null-byte-in-string/error +++ b/test/suites/invalid/null-byte-in-string/error @@ -1,2 +1,2 @@ 1 -\u0000 is not allowed +control character 0x0 near '"null byte ' diff --git a/test/suites/invalid/null-byte-in-string/input b/test/suites/invalid/null-byte-in-string/input Binary files differindex 22ae82b..268d1f1 100644 --- a/test/suites/invalid/null-byte-in-string/input +++ b/test/suites/invalid/null-byte-in-string/input diff --git a/test/suites/invalid/null-byte-outside-string/error b/test/suites/invalid/null-byte-outside-string/error new file mode 100644 index 0000000..f0e68ec --- /dev/null +++ b/test/suites/invalid/null-byte-outside-string/error @@ -0,0 +1,2 @@ +1 +invalid token near end of file diff --git a/test/suites/invalid/null-byte-outside-string/input b/test/suites/invalid/null-byte-outside-string/input Binary files differnew file mode 100644 index 0000000..aa550eb --- /dev/null +++ b/test/suites/invalid/null-byte-outside-string/input diff --git a/test/suites/invalid/real-underflow/error b/test/suites/invalid/real-underflow/error deleted file mode 100644 index 1b65d40..0000000 --- a/test/suites/invalid/real-underflow/error +++ /dev/null @@ -1,2 +0,0 @@ -1 -real number underflow near '123e-10000000' diff --git a/test/suites/invalid-strip/real-underflow/input b/test/suites/valid-strip/real-underflow/input index c5236eb..c5236eb 100644 --- a/test/suites/invalid-strip/real-underflow/input +++ b/test/suites/valid-strip/real-underflow/input diff --git a/test/suites/valid-strip/real-underflow/output b/test/suites/valid-strip/real-underflow/output new file mode 100644 index 0000000..92df1df --- /dev/null +++ b/test/suites/valid-strip/real-underflow/output @@ -0,0 +1 @@ +[0.0]
\ No newline at end of file diff --git a/test/suites/invalid/real-underflow/input b/test/suites/valid/real-underflow/input index dc70996..dc70996 100644 --- a/test/suites/invalid/real-underflow/input +++ b/test/suites/valid/real-underflow/input diff --git a/test/suites/valid/real-underflow/output b/test/suites/valid/real-underflow/output new file mode 100644 index 0000000..92df1df --- /dev/null +++ b/test/suites/valid/real-underflow/output @@ -0,0 +1 @@ +[0.0]
\ No newline at end of file |