More work on json_pack error reporting.
* Remove errant line-feed from pack_object error message. * Correct error message in pack_object_inter. * Create pack_integer / pack_real to get the correct error messages on failure when packing numeric values. * Add tests for packing NAN and infinity directly, in an array and as an object value.
This commit is contained in:
parent
5df5fc5b13
commit
8d659113d5
@ -261,7 +261,7 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|||||||
jsonp_free(key);
|
jsonp_free(key);
|
||||||
|
|
||||||
if(valueOptional != '*') {
|
if(valueOptional != '*') {
|
||||||
set_error(s, "<args>", json_error_null_value, "NULL object value\n");
|
set_error(s, "<args>", json_error_null_value, "NULL object value");
|
||||||
s->has_error = 1;
|
s->has_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,11 +396,47 @@ static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_error(s, "<args>", json_error_null_value, "NULL object key");
|
set_error(s, "<args>", json_error_null_value, "NULL object");
|
||||||
s->has_error = 1;
|
s->has_error = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static json_t *pack_integer(scanner_t *s, json_int_t value)
|
||||||
|
{
|
||||||
|
json_t *json = json_integer(value);
|
||||||
|
|
||||||
|
if (!json) {
|
||||||
|
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
||||||
|
s->has_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
static json_t *pack_real(scanner_t *s, double value)
|
||||||
|
{
|
||||||
|
/* Allocate without setting value so we can identify OOM error. */
|
||||||
|
json_t *json = json_real(0.0);
|
||||||
|
|
||||||
|
if (!json) {
|
||||||
|
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
||||||
|
s->has_error = 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_real_set(json, value)) {
|
||||||
|
json_decref(json);
|
||||||
|
|
||||||
|
set_error(s, "<args>", json_error_numeric_overflow, "Invalid floating point value");
|
||||||
|
s->has_error = 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
static json_t *pack(scanner_t *s, va_list *ap)
|
static json_t *pack(scanner_t *s, va_list *ap)
|
||||||
{
|
{
|
||||||
switch(token(s)) {
|
switch(token(s)) {
|
||||||
@ -420,13 +456,13 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|||||||
return va_arg(*ap, int) ? json_true() : json_false();
|
return va_arg(*ap, int) ? json_true() : json_false();
|
||||||
|
|
||||||
case 'i': /* integer from int */
|
case 'i': /* integer from int */
|
||||||
return json_integer(va_arg(*ap, int));
|
return pack_integer(s, va_arg(*ap, int));
|
||||||
|
|
||||||
case 'I': /* integer from json_int_t */
|
case 'I': /* integer from json_int_t */
|
||||||
return json_integer(va_arg(*ap, json_int_t));
|
return pack_integer(s, va_arg(*ap, json_int_t));
|
||||||
|
|
||||||
case 'f': /* real */
|
case 'f': /* real */
|
||||||
return json_real(va_arg(*ap, double));
|
return pack_real(s, va_arg(*ap, double));
|
||||||
|
|
||||||
case 'O': /* a json_t object; increments refcount */
|
case 'O': /* a json_t object; increments refcount */
|
||||||
return pack_object_inter(s, ap, 1);
|
return pack_object_inter(s, ap, 1);
|
||||||
|
@ -15,8 +15,39 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifdef INFINITY
|
||||||
|
// This test triggers "warning C4756: overflow in constant arithmetic"
|
||||||
|
// in Visual Studio. This warning is triggered here by design, so disable it.
|
||||||
|
// (This can only be done on function level so we keep these tests separate)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning (disable: 4756)
|
||||||
|
#endif
|
||||||
|
static void test_inifity()
|
||||||
|
{
|
||||||
|
json_error_t error;
|
||||||
|
|
||||||
|
if (json_pack_ex(&error, 0, "f", INFINITY))
|
||||||
|
fail("json_pack infinity incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 1, 1);
|
||||||
|
|
||||||
|
if (json_pack_ex(&error, 0, "[f]", INFINITY))
|
||||||
|
fail("json_pack infinity array element incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 2, 2);
|
||||||
|
|
||||||
|
if (json_pack_ex(&error, 0, "{s:f}", "key", INFINITY))
|
||||||
|
fail("json_pack infinity object value incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 4, 4);
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // INFINITY
|
||||||
|
|
||||||
static void run_tests()
|
static void run_tests()
|
||||||
{
|
{
|
||||||
json_t *value;
|
json_t *value;
|
||||||
@ -313,6 +344,25 @@ static void run_tests()
|
|||||||
fail("json_pack array optional failed");
|
fail("json_pack array optional failed");
|
||||||
json_decref(value);
|
json_decref(value);
|
||||||
|
|
||||||
|
#ifdef NAN
|
||||||
|
/* Invalid float values */
|
||||||
|
if (json_pack_ex(&error, 0, "f", NAN))
|
||||||
|
fail("json_pack NAN incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 1, 1);
|
||||||
|
|
||||||
|
if (json_pack_ex(&error, 0, "[f]", NAN))
|
||||||
|
fail("json_pack NAN array element incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 2, 2);
|
||||||
|
|
||||||
|
if (json_pack_ex(&error, 0, "{s:f}", "key", NAN))
|
||||||
|
fail("json_pack NAN object value incorrectly succeeded");
|
||||||
|
check_error(json_error_numeric_overflow, "Invalid floating point value", "<args>", 1, 4, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INFINITY
|
||||||
|
test_inifity();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Whitespace; regular string */
|
/* Whitespace; regular string */
|
||||||
value = json_pack(" s\t ", "test");
|
value = json_pack(" s\t ", "test");
|
||||||
if(!json_is_string(value) || strcmp("test", json_string_value(value)))
|
if(!json_is_string(value) || strcmp("test", json_string_value(value)))
|
||||||
@ -439,9 +489,9 @@ static void run_tests()
|
|||||||
|
|
||||||
if(json_pack_ex(&error, 0, "{s:o}", "foo", NULL))
|
if(json_pack_ex(&error, 0, "{s:o}", "foo", NULL))
|
||||||
fail("json_pack failed to catch nullable object");
|
fail("json_pack failed to catch nullable object");
|
||||||
check_error(json_error_null_value, "NULL object key", "<args>", 1, 4, 4);
|
check_error(json_error_null_value, "NULL object", "<args>", 1, 4, 4);
|
||||||
|
|
||||||
if(json_pack_ex(&error, 0, "{s:O}", "foo", NULL))
|
if(json_pack_ex(&error, 0, "{s:O}", "foo", NULL))
|
||||||
fail("json_pack failed to catch nullable incref object");
|
fail("json_pack failed to catch nullable incref object");
|
||||||
check_error(json_error_null_value, "NULL object key", "<args>", 1, 4, 4);
|
check_error(json_error_null_value, "NULL object", "<args>", 1, 4, 4);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user