aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Lehtinen <petri@digip.org>2010-03-28 21:44:41 +0300
committerPetri Lehtinen <petri@digip.org>2010-03-28 21:44:41 +0300
commit4e63fcd55d874485071073f181dbfc5b9e196600 (patch)
tree8c1aa0262a7ee2cdd6cc5c56b06b76660fd2d45e
parent49880cbabeb597a9c748a3d5f37e9961a084dce3 (diff)
parent024106bbfbd7376656876aa8bd00a333d5ada10c (diff)
downloadjansson-4e63fcd55d874485071073f181dbfc5b9e196600.zip
jansson-4e63fcd55d874485071073f181dbfc5b9e196600.tar.gz
jansson-4e63fcd55d874485071073f181dbfc5b9e196600.tar.bz2
Merge branch '1.2'
Conflicts: configure.ac
-rw-r--r--.gitignore1
-rw-r--r--configure.ac11
-rw-r--r--doc/conformance.rst102
-rw-r--r--doc/index.rst1
-rw-r--r--src/hashtable.c2
-rw-r--r--src/jansson.h.in (renamed from src/jansson.h)21
-rw-r--r--src/load.c9
-rw-r--r--src/value.c3
-rw-r--r--test/suites/invalid-strip/escaped-null-byte-in-string/error2
-rw-r--r--test/suites/invalid-strip/escaped-null-byte-in-string/input1
-rw-r--r--test/suites/invalid-strip/null-byte-in-string/error2
-rw-r--r--test/suites/invalid-strip/null-byte-in-string/inputbin34 -> 27 bytes
-rw-r--r--test/suites/invalid-strip/null-byte-outside-string/error2
-rw-r--r--test/suites/invalid-strip/null-byte-outside-string/inputbin0 -> 2 bytes
-rw-r--r--test/suites/invalid-strip/real-underflow/error2
-rw-r--r--test/suites/invalid/escaped-null-byte-in-string/error2
-rw-r--r--test/suites/invalid/escaped-null-byte-in-string/input1
-rw-r--r--test/suites/invalid/null-byte-in-string/error2
-rw-r--r--test/suites/invalid/null-byte-in-string/inputbin35 -> 28 bytes
-rw-r--r--test/suites/invalid/null-byte-outside-string/error2
-rw-r--r--test/suites/invalid/null-byte-outside-string/inputbin0 -> 3 bytes
-rw-r--r--test/suites/invalid/real-underflow/error2
-rw-r--r--test/suites/valid-strip/real-underflow/input (renamed from test/suites/invalid-strip/real-underflow/input)0
-rw-r--r--test/suites/valid-strip/real-underflow/output1
-rw-r--r--test/suites/valid/real-underflow/input (renamed from test/suites/invalid/real-underflow/input)0
-rw-r--r--test/suites/valid/real-underflow/output1
26 files changed, 147 insertions, 23 deletions
diff --git a/.gitignore b/.gitignore
index c33c1fc..db44e75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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));
diff --git a/src/load.c b/src/load.c
index baf3183..649609a 100644
--- a/src/load.c
+++ b/src/load.c
@@ -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
index 60f7f7b..c0d82be 100644
--- a/test/suites/invalid-strip/null-byte-in-string/input
+++ b/test/suites/invalid-strip/null-byte-in-string/input
Binary files differ
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
new file mode 100644
index 0000000..75447d8
--- /dev/null
+++ b/test/suites/invalid-strip/null-byte-outside-string/input
Binary files differ
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
index 22ae82b..268d1f1 100644
--- a/test/suites/invalid/null-byte-in-string/input
+++ b/test/suites/invalid/null-byte-in-string/input
Binary files differ
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
new file mode 100644
index 0000000..aa550eb
--- /dev/null
+++ b/test/suites/invalid/null-byte-outside-string/input
Binary files differ
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