Path: blob/main/crypto/krb5/src/util/support/t_json.c
34889 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* util/support/t_json.c - JSON test program */2/*3* Copyright (c) 2010 Kungliga Tekniska Högskolan4* (Royal Institute of Technology, Stockholm, Sweden).5* All rights reserved.6*7* Portions Copyright (c) 2010 Apple Inc. All rights reserved.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12*13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer.15*16* 2. Redistributions in binary form must reproduce the above copyright17* notice, this list of conditions and the following disclaimer in the18* documentation and/or other materials provided with the distribution.19*20* 3. Neither the name of the Institute nor the names of its contributors21* may be used to endorse or promote products derived from this software22* without specific prior written permission.23*24* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND25* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE26* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE27* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE28* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL29* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS30* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)31* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT32* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY33* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF34* SUCH DAMAGE.35*/36/*37* Copyright (C) 2012 by the Massachusetts Institute of Technology.38* All rights reserved.39*40* Redistribution and use in source and binary forms, with or without41* modification, are permitted provided that the following conditions42* are met:43*44* * Redistributions of source code must retain the above copyright45* notice, this list of conditions and the following disclaimer.46*47* * Redistributions in binary form must reproduce the above copyright48* notice, this list of conditions and the following disclaimer in49* the documentation and/or other materials provided with the50* distribution.51*52* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS53* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT54* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS55* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE56* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,57* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES58* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR59* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)60* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,61* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)62* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED63* OF THE POSSIBILITY OF SUCH DAMAGE.64*/6566#include <errno.h>67#include <stdio.h>68#include <stdlib.h>69#include <string.h>7071#include <k5-json.h>7273static void74err(const char *str)75{76fprintf(stderr, "%s\n", str);77exit(1);78}7980static void81check(int pred, const char *str)82{83if (!pred)84err(str);85}8687static void88test_array(void)89{90k5_json_string v1;91k5_json_number v2;92k5_json_null v3;93k5_json_array a;94k5_json_value v;9596k5_json_array_create(&a);97k5_json_string_create("abc", &v1);98k5_json_array_add(a, v1);99k5_json_number_create(2, &v2);100k5_json_array_add(a, v2);101k5_json_null_create(&v3);102k5_json_array_add(a, v3);103104check(k5_json_array_length(a) == 3, "array length");105v = k5_json_array_get(a, 2);106check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "array[2] tid");107v = k5_json_array_get(a, 1);108check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "array[1] tid");109check(k5_json_number_value(v) == 2, "array[1] value");110v = k5_json_array_get(a, 0);111check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "array[0] tid");112check(strcmp(k5_json_string_utf8(v), "abc") == 0, "array[0] value");113114k5_json_release(v1);115k5_json_release(v2);116k5_json_release(a);117118k5_json_array_fmt(&a, "vnbiLssB", v3, 1, 9, (long long)-6, "def", NULL,119(void *)"ghij", (size_t)4);120v = k5_json_array_get(a, 0);121check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[0] tid");122v = k5_json_array_get(a, 1);123check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[1] tid");124v = k5_json_array_get(a, 2);125check(k5_json_get_tid(v) == K5_JSON_TID_BOOL, "fmt array[2] tid");126check(k5_json_bool_value(v), "fmt array[2] value");127v = k5_json_array_get(a, 3);128check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[3] tid");129check(k5_json_number_value(v) == 9, "fmt array[3] value");130v = k5_json_array_get(a, 4);131check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[4] tid");132check(k5_json_number_value(v) == -6, "fmt array[4] value");133v = k5_json_array_get(a, 5);134check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[5] tid");135check(strcmp(k5_json_string_utf8(v), "def") == 0, "fmt array[5] value");136v = k5_json_array_get(a, 6);137check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[6] tid");138v = k5_json_array_get(a, 7);139check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[7] tid");140check(strcmp(k5_json_string_utf8(v), "Z2hpag==") == 0,141"fmt array[7] value");142k5_json_release(v3);143k5_json_release(a);144}145146static void147test_object(void)148{149k5_json_object object;150k5_json_number n, v1;151k5_json_string s, v2;152153k5_json_object_create(&object);154k5_json_number_create(1, &v1);155k5_json_object_set(object, "key1", v1);156k5_json_string_create("hejsan", &v2);157k5_json_object_set(object, "key2", v2);158159n = k5_json_object_get(object, "key1");160if (k5_json_number_value(n) != 1)161err("Retrieving key1 from object failed");162163s = k5_json_object_get(object, "key2");164if (strcmp(k5_json_string_utf8(s), "hejsan") != 0)165err("Retrieving key2 from object failed");166167check(k5_json_object_get(object, "key3") == NULL,168"object nonexistent key");169170k5_json_object_set(object, "key1", NULL);171check(k5_json_object_get(object, "key1") == NULL,172"object removed key");173check(k5_json_object_get(object, "key2") != NULL,174"object remaining key");175176k5_json_release(v1);177k5_json_release(v2);178k5_json_release(object);179}180181static void182test_string(void)183{184k5_json_string s1, s2, s3;185unsigned char *data;186size_t len;187188k5_json_string_create("hejsan", &s1);189k5_json_string_create("hejsan", &s2);190k5_json_string_create_base64("55555", 5, &s3);191192if (strcmp(k5_json_string_utf8(s1), k5_json_string_utf8(s2)) != 0)193err("Identical strings are not identical");194if (strcmp(k5_json_string_utf8(s3), "NTU1NTU=") != 0)195err("base64 string has incorrect value");196k5_json_string_unbase64(s3, &data, &len);197if (len != 5 || memcmp(data, "55555", 5) != 0)198err("base64 string doesn't decode to correct value");199free(data);200201k5_json_release(s1);202k5_json_release(s2);203k5_json_release(s3);204}205206static void207test_json(void)208{209static char *tests[] = {210"{\"k1\":\"s1\",\"k2\":\"s2\"}",211"{\"k1\":[\"s1\",\"s2\",\"s3\"],\"k2\":\"s3\"}",212"{\"k1\":{\"k2\":\"s1\",\"k3\":\"s2\",\"k4\":\"s3\"},\"k5\":\"s4\"}",213"[\"v1\",\"v2\",[\"v3\",\"v4\",[\"v 5\",\" v 7 \"]],-123456789,"214"null,true,false,123456789,\"\"]",215"-1",216"\"\\\\abc\\\"\\nde\\b\\r/\\ff\\tghi\\u0001\\u001F\"",217"9223372036854775807",218"-9223372036854775808",219NULL220};221char **tptr, *s, *enc, *p, orig;222int i;223k5_json_value v, v2;224225check(k5_json_decode("\"string\"", &v) == 0, "string1");226check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "string1 tid");227check(strcmp(k5_json_string_utf8(v), "string") == 0, "string1 utf8");228k5_json_release(v);229230check(k5_json_decode("\t \"foo\\\"bar\" ", &v) == 0, "string2");231check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "string2 tid");232check(strcmp(k5_json_string_utf8(v), "foo\"bar") == 0, "string2 utf8");233k5_json_release(v);234235check(k5_json_decode(" { \"key\" : \"value\" }", &v) == 0, "object1");236check(k5_json_get_tid(v) == K5_JSON_TID_OBJECT, "object1 tid");237v2 = k5_json_object_get(v, "key");238check(v2 != NULL, "object[key]");239check(k5_json_get_tid(v2) == K5_JSON_TID_STRING, "object1[key] tid");240check(strcmp(k5_json_string_utf8(v2), "value") == 0, "object1[key] utf8");241k5_json_release(v);242243check(k5_json_decode("{ \"k1\" : { \"k2\" : \"s2\", \"k3\" : \"s3\" }, "244"\"k4\" : \"s4\" }", &v) == 0, "object2");245v2 = k5_json_object_get(v, "k1");246check(v2 != NULL, "object2[k1]");247check(k5_json_get_tid(v2) == K5_JSON_TID_OBJECT, "object2[k1] tid");248v2 = k5_json_object_get(v2, "k3");249check(v2 != NULL, "object2[k1][k3]");250check(k5_json_get_tid(v2) == K5_JSON_TID_STRING, "object2[k1][k3] tid");251check(strcmp(k5_json_string_utf8(v2), "s3") == 0, "object2[k1][k3] utf8");252k5_json_release(v);253254check(k5_json_decode("{ \"k1\" : 1 }", &v) == 0, "object3");255check(k5_json_get_tid(v) == K5_JSON_TID_OBJECT, "object3 id");256v2 = k5_json_object_get(v, "k1");257check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "object3[k1] tid");258check(k5_json_number_value(v2) == 1, "object3[k1] value");259k5_json_release(v);260261check(k5_json_decode("-10", &v) == 0, "number1");262check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "number1 tid");263check(k5_json_number_value(v) == -10, "number1 value");264k5_json_release(v);265266check(k5_json_decode("99", &v) == 0, "number2");267check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "number2 tid");268check(k5_json_number_value(v) == 99, "number2 value");269k5_json_release(v);270271check(k5_json_decode(" [ 1 ]", &v) == 0, "array1");272check(k5_json_get_tid(v) == K5_JSON_TID_ARRAY, "array1 tid");273check(k5_json_array_length(v) == 1, "array1 len");274v2 = k5_json_array_get(v, 0);275check(v2 != NULL, "array1[0]");276check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "array1[0] tid");277check(k5_json_number_value(v2) == 1, "array1[0] value");278k5_json_release(v);279280check(k5_json_decode(" [ -1 ]", &v) == 0, "array2");281check(k5_json_get_tid(v) == K5_JSON_TID_ARRAY, "array2 tid");282check(k5_json_array_length(v) == 1, "array2 len");283v2 = k5_json_array_get(v, 0);284check(v2 != NULL, "array2[0]");285check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "array2[0] tid");286check(k5_json_number_value(v2) == -1, "array2[0] value");287k5_json_release(v);288289check(k5_json_decode("18446744073709551616", &v) == EOVERFLOW,290"unsigned 64-bit overflow");291check(k5_json_decode("9223372036854775808", &v) == EOVERFLOW,292"signed 64-bit positive overflow");293check(k5_json_decode("-9223372036854775809", &v) == EOVERFLOW,294"signed 64-bit negative overflow");295296for (tptr = tests; *tptr != NULL; tptr++) {297s = strdup(*tptr);298if (k5_json_decode(s, &v))299err(s);300if (k5_json_encode(v, &enc) || strcmp(enc, s) != 0)301err(s);302free(enc);303k5_json_release(v);304305/* Fuzz bytes. Parsing may succeed or fail; we're just looking for306* memory access bugs. */307for (p = s; *p != '\0'; p++) {308orig = *p;309for (i = 0; i <= 255; i++) {310*p = i;311k5_json_decode(s, &v);312k5_json_release(v);313}314*p = orig;315}316free(s);317}318}319320int321main(int argc, char **argv)322{323test_array();324test_object();325test_string();326test_json();327return 0;328}329330331