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 12static 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 37static 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 46static 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 64static 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 90static 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 118static 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 138static 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 160static 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 177static 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