11 Commits
v2.0 ... v2.0.1

Author SHA1 Message Date
Petri Lehtinen
1c0a3b2a55 jansson 2.0.1 2011-03-31 16:59:26 +03:00
Petri Lehtinen
eab23f05d8 Fix a few malloc() and free() calls
Replace them with jsonp_malloc() and jsonp_free() to support the
custom memory allocation.
2011-03-31 16:37:43 +03:00
Petri Lehtinen
0944ac8d91 Fix invalid object key hashing in json_unpack() strict checking mode
The keys which are stored temporarily to a hashtable to make sure that
all object keys are unpacked, were hashed with the object key hashing
function. It is meant to compute hashes for object_key_t values, and
it works incorrectly for plain strings.

Fixed by introducing suitable functions for hashing and comparing
strings for string-keyed hashtables.
2011-03-30 12:57:48 +03:00
Petri Lehtinen
279d8bf108 Use the correct number of parens in JANSSON_VERSION_HEX macro 2011-03-27 14:12:40 +03:00
Petri Lehtinen
38e35e0973 Test framework enhancements, fix the check_exports test
* Use "printf" instead of "echo -n" as it's more portable
* Treat a test as skipped if it exits with exit status of 77
* Skip the check_exports test if "nm -D" doesn't work
2011-03-27 13:34:43 +03:00
Petri Lehtinen
c30e92603c ANSI C requires struct initializers to be constant expressions
Closes GH-17.
2011-03-21 09:28:14 +02:00
Petri Lehtinen
6ecba84817 Fix json_object_size() return value
Return 0 as documented if the argument is not a JSON object.

Closes GH-18.
2011-03-21 08:22:34 +02:00
Petri Lehtinen
b90ed1accb Enhance portability of va_copy()
va_copy() is a C99 feature. In C89 implementations, it's sometimes
available as __va_copy(). If not, memcpy() should do the trick.
2011-03-20 21:23:37 +02:00
Petri Lehtinen
1111960120 Fix a declaration after statement
While at it, add -Wdeclaration-after-statement to AM_CFLAGS to catch
these in the future.
2011-03-10 21:28:53 +02:00
Petri Lehtinen
7f09f48e7e Distribute doc/upgrading.rst
Closes GH-16.
2011-03-10 21:26:18 +02:00
Petri Lehtinen
b397711a66 Check documentation in make distcheck
It seems that the only way to do this is to use the dvi make target,
as it's built in make distcheck after running configure.
2011-03-10 21:24:45 +02:00
17 changed files with 135 additions and 53 deletions

31
CHANGES
View File

@@ -1,3 +1,34 @@
Version 2.0.1
=============
Released 2011-03-31
* Bug fixes:
- Replace a few `malloc()` and `free()` calls with their
counterparts that support custom memory management.
- Fix object key hashing in json_unpack() strict checking mode.
- Fix the parentheses in JANSSON_VERSION_HEX macro.
- Fix `json_object_size()` return value.
- Fix a few compilation issues.
* Portability:
- Enhance portability of `va_copy()`.
- Test framework portability enhancements.
* Documentation:
- Distribute ``doc/upgrading.rst`` with the source tarball.
- Build documentation in strict mode in ``make distcheck``.
Version 2.0
===========

View File

@@ -1,7 +1,9 @@
EXTRA_DIST = CHANGES LICENSE README.rst
SUBDIRS = doc src test
check-doc:
# "make distcheck" builds the dvi target, so use it to check that the
# documentation is built correctly.
dvi:
$(MAKE) SPHINXOPTS_EXTRA=-W html
pkgconfigdir = $(libdir)/pkgconfig

View File

@@ -1,5 +1,5 @@
AC_PREREQ([2.60])
AC_INIT([jansson], [2.0], [petri@digip.org])
AC_INIT([jansson], [2.0.1], [petri@digip.org])
AM_INIT_AUTOMAKE([1.10 foreign])

View File

@@ -1,6 +1,6 @@
EXTRA_DIST = conf.py apiref.rst changes.rst conformance.rst \
gettingstarted.rst github_commits.c index.rst tutorial.rst \
ext/refcounting.py
upgrading.rst ext/refcounting.py
SPHINXBUILD = sphinx-build
SPHINXOPTS = -d _build/doctrees $(SPHINXOPTS_EXTRA)

View File

@@ -50,7 +50,7 @@ copyright = u'2009-2011, Petri Lehtinen'
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '2.0'
release = '2.0.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -17,9 +17,9 @@ libjansson_la_SOURCES = \
value.c
libjansson_la_LDFLAGS = \
-export-symbols-regex '^json_' \
-version-info 4:0:0
-version-info 4:1:0
if GCC
# These flags are gcc specific
AM_CFLAGS = -Wall -Wextra -Werror
AM_CFLAGS = -Wall -Wextra -Wdeclaration-after-statement -Werror
endif

View File

@@ -18,10 +18,12 @@ void jsonp_error_init(json_error_t *error, const char *source)
void jsonp_error_set_source(json_error_t *error, const char *source)
{
size_t length;
if(!error || !source)
return;
size_t length = strlen(source);
length = strlen(source);
if(length < JSON_ERROR_SOURCE_LENGTH)
strcpy(error->source, source);
else {

View File

@@ -126,7 +126,7 @@ static int hashtable_do_del(hashtable_t *hashtable,
if(hashtable->free_value)
hashtable->free_value(pair->value);
free(pair);
jsonp_free(pair);
hashtable->size--;
return 0;

View File

@@ -22,16 +22,16 @@ extern "C" {
#define JANSSON_MAJOR_VERSION 2
#define JANSSON_MINOR_VERSION 0
#define JANSSON_MICRO_VERSION 0
#define JANSSON_MICRO_VERSION 1
/* Micro version is omitted if it's 0 */
#define JANSSON_VERSION "2.0"
#define JANSSON_VERSION "2.0.1"
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \
(JANSSON_MINOR_VERSION << 8) | \
(JANSSON_MICRO_VERSION << 0)))
(JANSSON_MICRO_VERSION << 0))
/* types */

View File

@@ -9,7 +9,6 @@
#define JANSSON_PRIVATE_H
#include <stddef.h>
#include <stdarg.h>
#include "jansson.h"
#include "hashtable.h"
@@ -21,6 +20,16 @@
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
/* va_copy is a C99 feature. In C89 implementations, it's sometimes
available as __va_copy. If not, memcpy() should do the trick. */
#ifndef va_copy
#ifdef __va_copy
#define va_copy __va_copy
#else
#define va_copy(a, b) memcpy(&(a), &(b), sizeof(va_list))
#endif
#endif
typedef struct {
json_t json;
hashtable_t hashtable;
@@ -57,8 +66,8 @@ typedef struct {
#define json_to_real(json_) container_of(json_, json_real_t, json)
#define json_to_integer(json_) container_of(json_, json_integer_t, json)
size_t jsonp_hash_key(const void *ptr);
int jsonp_key_equal(const void *ptr1, const void *ptr2);
size_t jsonp_hash_str(const void *ptr);
int jsonp_str_equal(const void *ptr1, const void *ptr2);
typedef struct {
size_t serial;

View File

@@ -12,7 +12,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <jansson.h>
@@ -840,10 +839,13 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error)
{
lex_t lex;
json_t *result;
string_data_t stream_data = {string, 0};
string_data_t stream_data;
(void)flags; /* unused */
stream_data.data = string;
stream_data.pos = 0;
if(lex_init(&lex, string_get, (void *)&stream_data))
return NULL;

View File

@@ -233,7 +233,7 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
*/
hashtable_t key_set;
if(hashtable_init(&key_set, jsonp_hash_key, jsonp_key_equal, NULL, NULL)) {
if(hashtable_init(&key_set, jsonp_hash_str, jsonp_str_equal, NULL, NULL)) {
set_error(s, "<internal>", "Out of memory");
return -1;
}

View File

@@ -19,7 +19,7 @@ int strbuffer_init(strbuffer_t *strbuff)
strbuff->size = STRBUFFER_MIN_SIZE;
strbuff->length = 0;
strbuff->value = malloc(strbuff->size);
strbuff->value = jsonp_malloc(strbuff->size);
if(!strbuff->value)
return -1;
@@ -30,7 +30,7 @@ int strbuffer_init(strbuffer_t *strbuff)
void strbuffer_close(strbuffer_t *strbuff)
{
free(strbuff->value);
jsonp_free(strbuff->value);
strbuff->size = 0;
strbuff->length = 0;
strbuff->value = NULL;

View File

@@ -26,15 +26,10 @@ static JSON_INLINE void json_init(json_t *json, json_type type)
/*** object ***/
/* This macro just returns a pointer that's a few bytes backwards from
string. This makes it possible to pass a pointer to object_key_t
when only the string inside it is used, without actually creating
an object_key_t instance. */
#define string_to_key(string) container_of(string, object_key_t, key)
size_t jsonp_hash_key(const void *ptr)
/* From http://www.cse.yorku.ca/~oz/hash.html */
size_t jsonp_hash_str(const void *ptr)
{
const char *str = ((const object_key_t *)ptr)->key;
const char *str = (const char *)ptr;
size_t hash = 5381;
size_t c;
@@ -48,10 +43,26 @@ size_t jsonp_hash_key(const void *ptr)
return hash;
}
int jsonp_key_equal(const void *ptr1, const void *ptr2)
int jsonp_str_equal(const void *ptr1, const void *ptr2)
{
return strcmp(((const object_key_t *)ptr1)->key,
((const object_key_t *)ptr2)->key) == 0;
return strcmp((const char *)ptr1, (const char *)ptr2) == 0;
}
/* This macro just returns a pointer that's a few bytes backwards from
string. This makes it possible to pass a pointer to object_key_t
when only the string inside it is used, without actually creating
an object_key_t instance. */
#define string_to_key(string) container_of(string, object_key_t, key)
static size_t hash_key(const void *ptr)
{
return jsonp_hash_str(((const object_key_t *)ptr)->key);
}
static int key_equal(const void *ptr1, const void *ptr2)
{
return jsonp_str_equal(((const object_key_t *)ptr1)->key,
((const object_key_t *)ptr2)->key);
}
static void value_decref(void *value)
@@ -67,7 +78,7 @@ json_t *json_object(void)
json_init(&object->json, JSON_OBJECT);
if(hashtable_init(&object->hashtable,
jsonp_hash_key, jsonp_key_equal,
hash_key, key_equal,
jsonp_free, value_decref))
{
jsonp_free(object);
@@ -91,7 +102,7 @@ size_t json_object_size(const json_t *json)
json_object_t *object;
if(!json_is_object(json))
return -1;
return 0;
object = json_to_object(json);
return object->hashtable.size;

View File

@@ -30,31 +30,46 @@ for test_path in $suite_srcdir/*; do
rm -rf $test_log
mkdir -p $test_log
if [ $VERBOSE -eq 1 ]; then
echo -n "$test_name... "
printf '%s... ' "$test_name"
fi
if run_test; then
# Success
if [ $VERBOSE -eq 1 ]; then
echo "ok"
else
echo -n "."
fi
rm -rf $test_log
else
# Failure
if [ $VERBOSE -eq 1 ]; then
echo "FAILED"
else
echo -n "F"
fi
run_test
case $? in
0)
# Success
if [ $VERBOSE -eq 1 ]; then
printf 'ok\n'
else
printf '.'
fi
rm -rf $test_log
;;
[ $STOP -eq 1 ] && break
fi
77)
# Skip
if [ $VERBOSE -eq 1 ]; then
printf 'skipped\n'
else
printf 'S'
fi
rm -rf $test_log
;;
*)
# Failure
if [ $VERBOSE -eq 1 ]; then
printf 'FAILED\n'
else
printf 'F'
fi
[ $STOP -eq 1 ] && break
;;
esac
done
if [ $VERBOSE -eq 0 ]; then
echo
printf '\n'
fi
if [ -n "$(ls -A $suite_log)" ]; then

View File

@@ -89,7 +89,10 @@ EOF
SOFILE="../src/.libs/libjansson.so"
nm -D $SOFILE | grep ' T ' | cut -d' ' -f3 | sort >$test_log/output
nm -D $SOFILE >/dev/null >$test_log/symbols 2>/dev/null \
|| exit 77 # Skip if "nm -D" doesn't seem to work
grep ' T ' $test_log/symbols | cut -d' ' -f3 | sort >$test_log/output
if ! cmp -s $test_log/exports $test_log/output; then
diff -u $test_log/exports $test_log/output >&2

View File

@@ -122,6 +122,13 @@ int main()
fail("json_unpack simple array failed");
json_decref(j);
/* object with many items & strict checking */
j = json_pack("{s:i, s:i, s:i}", "a", 1, "b", 2, "c", 3);
rv = json_unpack(j, "{s:i, s:i, s:i}", "a", &i1, "b", &i2, "c", &i3);
if(rv || i1 != 1 || i2 != 2 || i3 != 3)
fail("json_unpack object with many items failed");
json_decref(j);
/*
* Invalid cases
*/
@@ -285,7 +292,7 @@ int main()
/* Unpack the same item twice */
j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42);
if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s))
fail("json_unpack object with strict validation failed");
fail("json_unpack object with strict validation failed");
check_error("1 object item(s) left unpacked", "<validation>", 1, 10, 10);
json_decref(j);