1 /*
2 * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
3 *
4 * Jansson is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8 #include <jansson.h>
9 #include <string.h>
10 #include "util.h"
11
file_not_found()12 static void file_not_found()
13 {
14 json_t *json;
15 json_error_t error;
16 char *pos;
17
18 json = json_load_file("/path/to/nonexistent/file.json", 0, &error);
19 if(json)
20 fail("json_load_file returned non-NULL for a nonexistent file");
21 if(error.line != -1)
22 fail("json_load_file returned an invalid line number");
23
24 /* The error message is locale specific, only check the beginning
25 of the error message. */
26
27 pos = strchr(error.text, ':');
28 if(!pos)
29 fail("json_load_file returne an invalid error message");
30
31 *pos = '\0';
32
33 if(strcmp(error.text, "unable to open /path/to/nonexistent/file.json") != 0)
34 fail("json_load_file returned an invalid error message");
35 }
36
reject_duplicates()37 static void reject_duplicates()
38 {
39 json_error_t error;
40
41 if(json_loads("{\"foo\": 1, \"foo\": 2}", JSON_REJECT_DUPLICATES, &error))
42 fail("json_loads did not detect a duplicate key");
43 check_error("duplicate object key near '\"foo\"'", "<string>", 1, 16, 16);
44 }
45
disable_eof_check()46 static void disable_eof_check()
47 {
48 json_error_t error;
49 json_t *json;
50
51 const char *text = "{\"foo\": 1} garbage";
52
53 if(json_loads(text, 0, &error))
54 fail("json_loads did not detect garbage after JSON text");
55 check_error("end of file expected near 'garbage'", "<string>", 1, 18, 18);
56
57 json = json_loads(text, JSON_DISABLE_EOF_CHECK, &error);
58 if(!json)
59 fail("json_loads failed with JSON_DISABLE_EOF_CHECK");
60
61 json_decref(json);
62 }
63
decode_any()64 static void decode_any()
65 {
66 json_t *json;
67 json_error_t error;
68
69 json = json_loads("\"foo\"", JSON_DECODE_ANY, &error);
70 if (!json || !json_is_string(json))
71 fail("json_load decoded any failed - string");
72 json_decref(json);
73
74 json = json_loads("42", JSON_DECODE_ANY, &error);
75 if (!json || !json_is_integer(json))
76 fail("json_load decoded any failed - integer");
77 json_decref(json);
78
79 json = json_loads("true", JSON_DECODE_ANY, &error);
80 if (!json || !json_is_true(json))
81 fail("json_load decoded any failed - boolean");
82 json_decref(json);
83
84 json = json_loads("null", JSON_DECODE_ANY, &error);
85 if (!json || !json_is_null(json))
86 fail("json_load decoded any failed - null");
87 json_decref(json);
88 }
89
decode_int_as_real()90 static void decode_int_as_real()
91 {
92 json_t *json;
93 json_error_t error;
94
95 #if JSON_INTEGER_IS_LONG_LONG
96 const char *imprecise;
97 json_int_t expected;
98 #endif
99
100 json = json_loads("42", JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY, &error);
101 if (!json || !json_is_real(json) || json_real_value(json) != 42.0)
102 fail("json_load decode int as real failed - int");
103 json_decref(json);
104
105 #if JSON_INTEGER_IS_LONG_LONG
106 /* This number cannot be represented exactly by a double */
107 imprecise = "9007199254740993";
108 expected = 9007199254740992ll;
109
110 json = json_loads(imprecise, JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY,
111 &error);
112 if (!json || !json_is_real(json) || expected != (json_int_t)json_real_value(json))
113 fail("json_load decode int as real failed - expected imprecision");
114 json_decref(json);
115 #endif
116 }
117
allow_nul()118 static void allow_nul()
119 {
120 const char *text = "\"nul byte \\u0000 in string\"";
121 const char *expected = "nul byte \0 in string";
122 size_t len = 20;
123 json_t *json;
124
125 json = json_loads(text, JSON_ALLOW_NUL | JSON_DECODE_ANY, NULL);
126 if(!json || !json_is_string(json))
127 fail("unable to decode embedded NUL byte");
128
129 if(json_string_length(json) != len)
130 fail("decoder returned wrong string length");
131
132 if(memcmp(json_string_value(json), expected, len + 1))
133 fail("decoder returned wrong string content");
134
135 json_decref(json);
136 }
137
load_wrong_args()138 static void load_wrong_args()
139 {
140 json_t *json;
141 json_error_t error;
142
143 json = json_loads(NULL, 0, &error);
144 if (json)
145 fail("json_loads should return NULL if the first argument is NULL");
146
147 json = json_loadb(NULL, 0, 0, &error);
148 if (json)
149 fail("json_loadb should return NULL if the first argument is NULL");
150
151 json = json_loadf(NULL, 0, &error);
152 if (json)
153 fail("json_loadf should return NULL if the first argument is NULL");
154
155 json = json_load_file(NULL, 0, &error);
156 if (json)
157 fail("json_loadf should return NULL if the first argument is NULL");
158 }
159
position()160 static void position()
161 {
162 json_t *json;
163 size_t flags = JSON_DISABLE_EOF_CHECK;
164 json_error_t error;
165
166 json = json_loads("{\"foo\": \"bar\"}", 0, &error);
167 if(error.position != 14)
168 fail("json_loads returned a wrong position");
169 json_decref(json);
170
171 json = json_loads("{\"foo\": \"bar\"} baz quux", flags, &error);
172 if(error.position != 14)
173 fail("json_loads returned a wrong position");
174 json_decref(json);
175 }
176
run_tests()177 static void run_tests()
178 {
179 file_not_found();
180 reject_duplicates();
181 disable_eof_check();
182 decode_any();
183 decode_int_as_real();
184 allow_nul();
185 load_wrong_args();
186 position();
187 }
188