2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file json/json_helper.c
22 * @brief functions to generate specifciations for JSON parsing
23 * @author Florian Dold
24 * @author Benedikt Mueller
25 * @author Christian Grothoff
28 #include "gnunet_json_lib.h"
32 * End of a parser specification.
34 struct GNUNET_JSON_Specification
35 GNUNET_JSON_spec_end ()
37 struct GNUNET_JSON_Specification ret = {
47 * Parse given JSON object to fixed size data
49 * @param cls closure, NULL
50 * @param root the json object representing data
51 * @param[out] spec where to write the data
52 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
55 parse_fixed_data (void *cls,
57 struct GNUNET_JSON_Specification *spec)
62 if (NULL == (enc = json_string_value (root)))
68 if (((len * 5) / 8) != spec->ptr_size)
74 GNUNET_STRINGS_string_to_data (enc,
87 * Variable size object (in network byte order, encoded using Crockford
88 * Base32hex encoding).
90 * @param name name of the JSON field
91 * @param[out] obj pointer where to write the data, must have @a size bytes
92 * @param size number of bytes expected in @a obj
94 struct GNUNET_JSON_Specification
95 GNUNET_JSON_spec_fixed (const char *name,
99 struct GNUNET_JSON_Specification ret = {
100 .parser = &parse_fixed_data,
113 * Parse given JSON object to variable size data
115 * @param cls closure, NULL
116 * @param root the json object representing data
117 * @param[out] spec where to write the data
118 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
121 parse_variable_data (void *cls,
123 struct GNUNET_JSON_Specification *spec)
130 str = json_string_value (root);
134 return GNUNET_SYSERR;
136 size = (strlen (str) * 5) / 8;
140 return GNUNET_SYSERR;
142 data = GNUNET_malloc (size);
143 res = GNUNET_STRINGS_string_to_data (str,
147 if (GNUNET_OK != res)
151 return GNUNET_SYSERR;
153 *(void**) spec->ptr = data;
154 *spec->size_ptr = size;
160 * Cleanup data left from parsing variable size data
162 * @param cls closure, NULL
163 * @param[out] spec where to free the data
166 clean_variable_data (void *cls,
167 struct GNUNET_JSON_Specification *spec)
169 if (0 != *spec->size_ptr)
171 GNUNET_free (*(void **) spec->ptr);
172 *(void**) spec->ptr = NULL;
179 * Variable size object (in network byte order, encoded using
180 * Crockford Base32hex encoding).
182 * @param name name of the JSON field
183 * @param[out] obj pointer where to write the data, will be allocated
184 * @param[out] size where to store the number of bytes allocated for @a obj
186 struct GNUNET_JSON_Specification
187 GNUNET_JSON_spec_varsize (const char *name,
191 struct GNUNET_JSON_Specification ret = {
192 .parser = &parse_variable_data,
193 .cleaner = &clean_variable_data,
207 * Parse given JSON object to string.
209 * @param cls closure, NULL
210 * @param root the json object representing data
211 * @param[out] spec where to write the data
212 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
215 parse_string (void *cls,
217 struct GNUNET_JSON_Specification *spec)
221 str = json_string_value (root);
225 return GNUNET_SYSERR;
227 *(const char **) spec->ptr = str;
233 * The expected field stores a string.
235 * @param name name of the JSON field
236 * @param strptr where to store a pointer to the field
238 struct GNUNET_JSON_Specification
239 GNUNET_JSON_spec_string (const char *name,
242 struct GNUNET_JSON_Specification ret = {
243 .parser = &parse_string,
257 * Parse given JSON object to a JSON object. (Yes, trivial.)
259 * @param cls closure, NULL
260 * @param root the json object representing data
261 * @param[out] spec where to write the data
262 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
265 parse_object (void *cls,
267 struct GNUNET_JSON_Specification *spec)
269 if (! (json_is_object (root) || json_is_array (root)) )
272 return GNUNET_SYSERR;
275 *(json_t **) spec->ptr = root;
281 * Cleanup data left from parsing JSON object.
283 * @param cls closure, NULL
284 * @param[out] spec where to free the data
287 clean_object (void *cls,
288 struct GNUNET_JSON_Specification *spec)
290 json_t **ptr = (json_t **) spec->ptr;
303 * @param name name of the JSON field
304 * @param[out] jsonp where to store the JSON found under @a name
306 struct GNUNET_JSON_Specification
307 GNUNET_JSON_spec_json (const char *name,
310 struct GNUNET_JSON_Specification ret = {
311 .parser = &parse_object,
312 .cleaner = &clean_object,
325 * Parse given JSON object to a uint8_t.
327 * @param cls closure, NULL
328 * @param root the json object representing data
329 * @param[out] spec where to write the data
330 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
335 struct GNUNET_JSON_Specification *spec)
338 uint8_t *up = spec->ptr;
340 if (! json_is_integer (root))
343 return GNUNET_SYSERR;
345 val = json_integer_value (root);
346 if ( (0 > val) || (val > UINT8_MAX) )
349 return GNUNET_SYSERR;
359 * @param name name of the JSON field
360 * @param[out] u8 where to store the integer found under @a name
362 struct GNUNET_JSON_Specification
363 GNUNET_JSON_spec_uint8 (const char *name,
366 struct GNUNET_JSON_Specification ret = {
372 .ptr_size = sizeof (uint8_t),
380 * Parse given JSON object to a uint16_t.
382 * @param cls closure, NULL
383 * @param root the json object representing data
384 * @param[out] spec where to write the data
385 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
388 parse_u16 (void *cls,
390 struct GNUNET_JSON_Specification *spec)
393 uint16_t *up = spec->ptr;
395 if (! json_is_integer (root))
398 return GNUNET_SYSERR;
400 val = json_integer_value (root);
401 if ( (0 > val) || (val > UINT16_MAX) )
404 return GNUNET_SYSERR;
406 *up = (uint16_t) val;
414 * @param name name of the JSON field
415 * @param[out] u16 where to store the integer found under @a name
417 struct GNUNET_JSON_Specification
418 GNUNET_JSON_spec_uint16 (const char *name,
421 struct GNUNET_JSON_Specification ret = {
422 .parser = &parse_u16,
427 .ptr_size = sizeof (uint16_t),
435 * Parse given JSON object to a uint32_t.
437 * @param cls closure, NULL
438 * @param root the json object representing data
439 * @param[out] spec where to write the data
440 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
443 parse_u32 (void *cls,
445 struct GNUNET_JSON_Specification *spec)
448 uint32_t *up = spec->ptr;
450 if (! json_is_integer (root))
453 return GNUNET_SYSERR;
455 val = json_integer_value (root);
456 if ( (0 > val) || (val > UINT32_MAX) )
459 return GNUNET_SYSERR;
461 *up = (uint32_t) val;
469 * @param name name of the JSON field
470 * @param[out] u32 where to store the integer found under @a name
472 struct GNUNET_JSON_Specification
473 GNUNET_JSON_spec_uint32 (const char *name,
476 struct GNUNET_JSON_Specification ret = {
477 .parser = &parse_u32,
482 .ptr_size = sizeof (uint32_t),
490 * Parse given JSON object to a uint8_t.
492 * @param cls closure, NULL
493 * @param root the json object representing data
494 * @param[out] spec where to write the data
495 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
498 parse_u64 (void *cls,
500 struct GNUNET_JSON_Specification *spec)
503 uint64_t *up = spec->ptr;
505 if (! json_is_integer (root))
508 return GNUNET_SYSERR;
510 val = json_integer_value (root);
511 *up = (uint64_t) val;
519 * @param name name of the JSON field
520 * @param[out] u64 where to store the integer found under @a name
522 struct GNUNET_JSON_Specification
523 GNUNET_JSON_spec_uint64 (const char *name,
526 struct GNUNET_JSON_Specification ret = {
527 .parser = &parse_u64,
532 .ptr_size = sizeof (uint64_t),
539 /* ************ GNUnet-specific parser specifications ******************* */
542 * Parse given JSON object to absolute time.
544 * @param cls closure, NULL
545 * @param root the json object representing data
546 * @param[out] spec where to write the data
547 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
550 parse_abs_time (void *cls,
552 struct GNUNET_JSON_Specification *spec)
554 struct GNUNET_TIME_Absolute *abs = spec->ptr;
556 unsigned long long int tval;
558 val = json_string_value (root);
562 return GNUNET_SYSERR;
564 if ( (0 == strcasecmp (val,
566 (0 == strcasecmp (val,
568 (0 == strcasecmp (val,
571 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
574 if (1 != sscanf (val,
579 return GNUNET_SYSERR;
581 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
582 abs->abs_value_us = tval * 1000LL * 1000LL;
583 if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
585 /* Integer overflow */
587 return GNUNET_SYSERR;
596 * @param name name of the JSON field
597 * @param[out] at where to store the absolute time found under @a name
599 struct GNUNET_JSON_Specification
600 GNUNET_JSON_spec_absolute_time (const char *name,
601 struct GNUNET_TIME_Absolute *at)
603 struct GNUNET_JSON_Specification ret = {
604 .parser = &parse_abs_time,
609 .ptr_size = sizeof (uint64_t),
617 * Parse given JSON object to absolute time.
619 * @param cls closure, NULL
620 * @param root the json object representing data
621 * @param[out] spec where to write the data
622 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
625 parse_abs_time_nbo (void *cls,
627 struct GNUNET_JSON_Specification *spec)
629 struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
631 unsigned long long int tval;
632 struct GNUNET_TIME_Absolute a;
634 val = json_string_value (root);
638 return GNUNET_SYSERR;
640 if ( (0 == strcasecmp (val,
642 (0 == strcasecmp (val,
644 (0 == strcasecmp (val,
647 *abs = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
650 if (1 != sscanf (val,
655 return GNUNET_SYSERR;
657 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
658 a.abs_value_us = tval * 1000LL * 1000LL;
659 if ( (a.abs_value_us) / 1000LL / 1000LL != tval)
661 /* Integer overflow */
663 return GNUNET_SYSERR;
665 *abs = GNUNET_TIME_absolute_hton (a);
671 * Absolute time in network byte order.
673 * @param name name of the JSON field
674 * @param[out] at where to store the absolute time found under @a name
676 struct GNUNET_JSON_Specification
677 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
678 struct GNUNET_TIME_AbsoluteNBO *at)
680 struct GNUNET_JSON_Specification ret = {
681 .parser = &parse_abs_time_nbo,
686 .ptr_size = sizeof (uint64_t),
694 * Parse given JSON object to relative time.
696 * @param cls closure, NULL
697 * @param root the json object representing data
698 * @param[out] spec where to write the data
699 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
702 parse_rel_time (void *cls,
704 struct GNUNET_JSON_Specification *spec)
706 struct GNUNET_TIME_Relative *rel = spec->ptr;
708 unsigned long long int tval;
710 val = json_string_value (root);
714 return GNUNET_SYSERR;
716 if ( (0 == strcasecmp (val,
719 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
722 if (1 != sscanf (val,
727 return GNUNET_SYSERR;
729 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
730 rel->rel_value_us = tval * 1000LL * 1000LL;
731 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
733 /* Integer overflow */
735 return GNUNET_SYSERR;
744 * @param name name of the JSON field
745 * @param[out] rt where to store the relative time found under @a name
747 struct GNUNET_JSON_Specification
748 GNUNET_JSON_spec_relative_time (const char *name,
749 struct GNUNET_TIME_Relative *rt)
751 struct GNUNET_JSON_Specification ret = {
752 .parser = &parse_rel_time,
757 .ptr_size = sizeof (uint64_t),
765 * Parse given JSON object to RSA public key.
767 * @param cls closure, NULL
768 * @param root the json object representing data
769 * @param[out] spec where to write the data
770 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
773 parse_rsa_public_key (void *cls,
775 struct GNUNET_JSON_Specification *spec)
777 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
783 if (NULL == (enc = json_string_value (root)))
786 return GNUNET_SYSERR;
789 buf_len = (len * 5) / 8;
790 buf = GNUNET_malloc (buf_len);
792 GNUNET_STRINGS_string_to_data (enc,
799 return GNUNET_SYSERR;
801 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
806 return GNUNET_SYSERR;
814 * Cleanup data left from parsing RSA public key.
816 * @param cls closure, NULL
817 * @param[out] spec where to free the data
820 clean_rsa_public_key (void *cls,
821 struct GNUNET_JSON_Specification *spec)
823 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
827 GNUNET_CRYPTO_rsa_public_key_free (*pk);
834 * Specification for parsing an RSA public key.
836 * @param name name of the JSON field
837 * @param pk where to store the RSA key found under @a name
839 struct GNUNET_JSON_Specification
840 GNUNET_JSON_spec_rsa_public_key (const char *name,
841 struct GNUNET_CRYPTO_RsaPublicKey **pk)
843 struct GNUNET_JSON_Specification ret = {
844 .parser = &parse_rsa_public_key,
845 .cleaner = &clean_rsa_public_key,
858 * Parse given JSON object to RSA signature.
860 * @param cls closure, NULL
861 * @param root the json object representing data
862 * @param[out] spec where to write the data
863 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
866 parse_rsa_signature (void *cls,
868 struct GNUNET_JSON_Specification *spec)
870 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
876 str = json_string_value (root);
880 return GNUNET_SYSERR;
882 size = (strlen (str) * 5) / 8;
883 buf = GNUNET_malloc (size);
884 res = GNUNET_STRINGS_string_to_data (str,
888 if (GNUNET_OK != res)
892 return GNUNET_SYSERR;
894 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
899 return GNUNET_SYSERR;
907 * Cleanup data left from parsing RSA signature.
909 * @param cls closure, NULL
910 * @param[out] spec where to free the data
913 clean_rsa_signature (void *cls,
914 struct GNUNET_JSON_Specification *spec)
916 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
920 GNUNET_CRYPTO_rsa_signature_free (*sig);
927 * Specification for parsing an RSA signature.
929 * @param name name of the JSON field
930 * @param sig where to store the RSA signature found under @a name
932 struct GNUNET_JSON_Specification
933 GNUNET_JSON_spec_rsa_signature (const char *name,
934 struct GNUNET_CRYPTO_RsaSignature **sig)
936 struct GNUNET_JSON_Specification ret = {
937 .parser = &parse_rsa_signature,
938 .cleaner = &clean_rsa_signature,
951 * Parse given JSON object to an int as a boolean.
953 * @param cls closure, NULL
954 * @param root the json object representing data
955 * @param[out] spec where to write the data
956 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
959 parse_boolean (void *cls,
961 struct GNUNET_JSON_Specification *spec)
965 if (! json_is_boolean (root))
968 return GNUNET_SYSERR;
970 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
976 * Boolean (true mapped to GNUNET_YES, false mapped to GNUNET_NO).
978 * @param name name of the JSON field
979 * @param[out] boolean where to store the boolean found under @a name
981 struct GNUNET_JSON_Specification
982 GNUNET_JSON_spec_boolean (const char *name,
985 struct GNUNET_JSON_Specification ret = {
986 .parser = &parse_boolean,
991 .ptr_size = sizeof (int),
998 /* end of json_helper.c */