Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12cd4e8c09 | ||
|
|
bad16ea52a | ||
|
|
30015bde90 | ||
|
|
19588c2d69 | ||
|
|
9c5a8430db | ||
|
|
afc9c1a23a | ||
|
|
b7bf96996f | ||
|
|
6d8c287032 | ||
|
|
ab3764ed0a | ||
|
|
9cc6fbe580 | ||
|
|
827a01937f | ||
|
|
0f62dac627 | ||
|
|
ab2d93b724 | ||
|
|
e4be4a4a28 | ||
|
|
78eda92908 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@ aclocal.m4
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
|
||||
28
CHANGES
Normal file
28
CHANGES
Normal file
@@ -0,0 +1,28 @@
|
||||
Version 1.0.4, released 2009-10-11
|
||||
|
||||
* Relax Autoconf version requirement to 2.59
|
||||
* Make Jansson compile on platforms where plain char is unsigned
|
||||
* Fix API tests for object
|
||||
|
||||
|
||||
Version 1.0.3, released 2009-09-14
|
||||
|
||||
* Check for integer and real overflows and underflows in decoder
|
||||
* Use the Python json module for tests, or simplejson if the json
|
||||
module is not found
|
||||
* Distribute changelog (this file)
|
||||
|
||||
|
||||
Version 1.0.2, released 2009-09-08
|
||||
|
||||
* Handle EOF correctly in decoder
|
||||
|
||||
|
||||
Version 1.0.1, released 2009-09-04
|
||||
|
||||
* Fixed broken json_is_boolean()
|
||||
|
||||
|
||||
Version 1.0, released 2009-08-25
|
||||
|
||||
* Initial release
|
||||
@@ -1,2 +1,2 @@
|
||||
EXTRA_DIST = LICENSE README.rst
|
||||
EXTRA_DIST = CHANGES LICENSE README.rst
|
||||
SUBDIRS = doc src test
|
||||
|
||||
59
config.h.in
59
config.h.in
@@ -1,59 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.63])
|
||||
AC_INIT([jansson], [1.0], [petri@digip.org])
|
||||
AC_PREREQ([2.59])
|
||||
AC_INIT([jansson], [1.0.4], [petri@digip.org])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign])
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ copyright = u'2009, Petri Lehtinen'
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
release = '1.0.4'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -13,6 +13,6 @@ libjansson_la_SOURCES = \
|
||||
utf.h \
|
||||
util.h \
|
||||
value.c
|
||||
libjansson_la_LDFLAGS = -version-info 0:0:0
|
||||
libjansson_la_LDFLAGS = -version-info 0:4:0
|
||||
|
||||
AM_CFLAGS = -Wall -Wextra -Werror -std=c99
|
||||
|
||||
@@ -70,7 +70,7 @@ static int dump_string(const char *str, dump_func dump, void *data)
|
||||
char seq[7];
|
||||
int length;
|
||||
|
||||
while(*end && *end != '\\' && *end != '"' && (*end < 0 || *end > 0x1F))
|
||||
while(*end && *end != '\\' && *end != '"' && (unsigned char)*end > 0x1F)
|
||||
end++;
|
||||
|
||||
if(end != str) {
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct {
|
||||
#define json_is_number(json) (json_is_integer(json) || json_is_real(json))
|
||||
#define json_is_true(json) (json && json_typeof(json) == JSON_TRUE)
|
||||
#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE)
|
||||
#define json_is_boolean(json) (jsin_is_true(json) || json_is_false(json))
|
||||
#define json_is_boolean(json) (json_is_true(json) || json_is_false(json))
|
||||
#define json_is_null(json) (json && json_typeof(json) == JSON_NULL)
|
||||
|
||||
/* construction, destruction, reference counting */
|
||||
|
||||
62
src/load.c
62
src/load.c
@@ -8,6 +8,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -134,10 +135,7 @@ static char stream_get(stream_t *stream, json_error_t *error)
|
||||
|
||||
c = stream->buffer[0];
|
||||
|
||||
if(c == EOF && stream->eof(stream->data))
|
||||
return EOF;
|
||||
|
||||
if(c < 0)
|
||||
if((unsigned char)c >= 0x80 && c != (char)EOF)
|
||||
{
|
||||
/* multi-byte UTF-8 sequence */
|
||||
int i, count;
|
||||
@@ -257,17 +255,17 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
|
||||
lex->value.string = NULL;
|
||||
lex->token = TOKEN_INVALID;
|
||||
|
||||
/* skip the " */
|
||||
c = lex_get_save(lex, error);
|
||||
|
||||
while(c != '"') {
|
||||
if(c == EOF) {
|
||||
if(c == (char)EOF) {
|
||||
lex_unget_unsave(lex, c);
|
||||
if(lex_eof(lex))
|
||||
error_set(error, lex, "premature end of input");
|
||||
goto out;
|
||||
}
|
||||
|
||||
else if(0 <= c && c <= 0x1F) {
|
||||
else if((unsigned char)c <= 0x1F) {
|
||||
/* control character */
|
||||
lex_unget_unsave(lex, c);
|
||||
if(c == '\n')
|
||||
@@ -402,10 +400,11 @@ out:
|
||||
free(lex->value.string);
|
||||
}
|
||||
|
||||
static void lex_scan_number(lex_t *lex, char c, json_error_t *error)
|
||||
static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
|
||||
{
|
||||
const char *saved_text;
|
||||
char *end;
|
||||
double value;
|
||||
|
||||
lex->token = TOKEN_INVALID;
|
||||
|
||||
@@ -426,14 +425,26 @@ static void lex_scan_number(lex_t *lex, char c, json_error_t *error)
|
||||
}
|
||||
|
||||
if(c != '.' && c != 'E' && c != 'e') {
|
||||
long value;
|
||||
|
||||
lex_unget_unsave(lex, c);
|
||||
lex->token = TOKEN_INTEGER;
|
||||
|
||||
saved_text = strbuffer_value(&lex->saved_text);
|
||||
lex->value.integer = strtol(saved_text, &end, 10);
|
||||
value = strtol(saved_text, &end, 10);
|
||||
assert(end == saved_text + lex->saved_text.length);
|
||||
|
||||
return;
|
||||
if((value == LONG_MAX && errno == ERANGE) || value > INT_MAX) {
|
||||
error_set(error, lex, "too big integer");
|
||||
goto out;
|
||||
}
|
||||
else if((value == LONG_MIN && errno == ERANGE) || value < INT_MIN) {
|
||||
error_set(error, lex, "too big negative integer");
|
||||
goto out;
|
||||
}
|
||||
|
||||
lex->token = TOKEN_INTEGER;
|
||||
lex->value.integer = (int)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(c == '.') {
|
||||
@@ -463,14 +474,29 @@ static void lex_scan_number(lex_t *lex, char c, json_error_t *error)
|
||||
}
|
||||
|
||||
lex_unget_unsave(lex, c);
|
||||
lex->token = TOKEN_REAL;
|
||||
|
||||
saved_text = strbuffer_value(&lex->saved_text);
|
||||
lex->value.real = strtod(saved_text, &end);
|
||||
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) {
|
||||
error_set(error, lex, "real number overflow");
|
||||
goto out;
|
||||
}
|
||||
|
||||
lex->token = TOKEN_REAL;
|
||||
lex->value.real = value;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int lex_scan(lex_t *lex, json_error_t *error)
|
||||
@@ -493,7 +519,7 @@ static int lex_scan(lex_t *lex, json_error_t *error)
|
||||
c = lex_get(lex, error);
|
||||
}
|
||||
|
||||
if(c == EOF) {
|
||||
if(c == (char)EOF) {
|
||||
if(lex_eof(lex))
|
||||
lex->token = TOKEN_EOF;
|
||||
else
|
||||
@@ -509,8 +535,10 @@ static int lex_scan(lex_t *lex, json_error_t *error)
|
||||
else if(c == '"')
|
||||
lex_scan_string(lex, error);
|
||||
|
||||
else if(isdigit(c) || c == '-')
|
||||
lex_scan_number(lex, c, error);
|
||||
else if(isdigit(c) || c == '-') {
|
||||
if(lex_scan_number(lex, c, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
else if(isupper(c) || islower(c)) {
|
||||
/* eat up the whole identifier for clearer error messages */
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
import simplejson
|
||||
import sys
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
def load(filename):
|
||||
try:
|
||||
@@ -17,14 +20,14 @@ def load(filename):
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
json = simplejson.load(jsonfile)
|
||||
jsondata = json.load(jsonfile)
|
||||
except ValueError, err:
|
||||
print "%s is malformed: %s" % (filename, err)
|
||||
sys.exit(1)
|
||||
finally:
|
||||
jsonfile.close()
|
||||
|
||||
return json
|
||||
return jsondata
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
|
||||
25
test/testdata/invalid
vendored
25
test/testdata/invalid
vendored
@@ -127,6 +127,21 @@ invalid token near '1e'
|
||||
====
|
||||
1
|
||||
invalid token near '1e'
|
||||
==== real-positive-overflow ====
|
||||
[123123e100000]
|
||||
====
|
||||
1
|
||||
real number overflow near '123123e100000'
|
||||
==== real-negative-overflow ====
|
||||
[-123123e100000]
|
||||
====
|
||||
1
|
||||
real number overflow near '-123123e100000'
|
||||
==== real-underflow ====
|
||||
[123e-10000000]
|
||||
====
|
||||
1
|
||||
real number underflow near '123e-10000000'
|
||||
==== integer-starting-with-zero ====
|
||||
[012]
|
||||
====
|
||||
@@ -137,6 +152,16 @@ invalid token near '0'
|
||||
====
|
||||
1
|
||||
invalid token near '-0'
|
||||
==== too-big-positive-integer ====
|
||||
[123123123123123]
|
||||
====
|
||||
1
|
||||
too big integer near '123123123123123'
|
||||
==== too-big-negative-integer ====
|
||||
[-123123123123123]
|
||||
====
|
||||
1
|
||||
too big negative integer near '-123123123123123'
|
||||
==== invalid-identifier ====
|
||||
[troo
|
||||
====
|
||||
|
||||
@@ -2,7 +2,7 @@ check_PROGRAMS = test_array test_number test_object
|
||||
|
||||
test_array_SOURCES = test_array.c util.h
|
||||
test_number_SOURCES = test_number.c util.h
|
||||
test_object_SOURCES = test_number.c util.h
|
||||
test_object_SOURCES = test_object.c util.h
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
AM_CFLAGS = -Wall -Werror
|
||||
|
||||
Reference in New Issue
Block a user