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 = {
48 * Parse given JSON object to fixed size data
50 * @param cls closure, NULL
51 * @param root the json object representing data
52 * @param[out] spec where to write the data
53 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
56 parse_fixed_data (void *cls,
58 struct GNUNET_JSON_Specification *spec)
63 if (NULL == (enc = json_string_value (root)))
69 if (((len * 5) / 8) != spec->ptr_size)
75 GNUNET_STRINGS_string_to_data (enc,
88 * Variable size object (in network byte order, encoded using Crockford
89 * Base32hex encoding).
91 * @param name name of the JSON field
92 * @param[out] obj pointer where to write the data, must have @a size bytes
93 * @param size number of bytes expected in @a obj
95 struct GNUNET_JSON_Specification
96 GNUNET_JSON_spec_fixed (const char *name,
100 struct GNUNET_JSON_Specification ret = {
101 .parser = &parse_fixed_data,
115 * Parse given JSON object to variable size data
117 * @param cls closure, NULL
118 * @param root the json object representing data
119 * @param[out] spec where to write the data
120 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
123 parse_variable_data (void *cls,
125 struct GNUNET_JSON_Specification *spec)
132 str = json_string_value (root);
136 return GNUNET_SYSERR;
138 size = (strlen (str) * 5) / 8;
142 return GNUNET_SYSERR;
144 data = GNUNET_malloc (size);
145 res = GNUNET_STRINGS_string_to_data (str,
149 if (GNUNET_OK != res)
153 return GNUNET_SYSERR;
155 *(void **) spec->ptr = data;
156 *spec->size_ptr = size;
162 * Cleanup data left from parsing variable size data
164 * @param cls closure, NULL
165 * @param[out] spec where to free the data
168 clean_variable_data (void *cls,
169 struct GNUNET_JSON_Specification *spec)
171 if (0 != *spec->size_ptr)
173 GNUNET_free (*(void **) spec->ptr);
174 *(void **) spec->ptr = NULL;
181 * Variable size object (in network byte order, encoded using
182 * Crockford Base32hex encoding).
184 * @param name name of the JSON field
185 * @param[out] obj pointer where to write the data, will be allocated
186 * @param[out] size where to store the number of bytes allocated for @a obj
188 struct GNUNET_JSON_Specification
189 GNUNET_JSON_spec_varsize (const char *name,
193 struct GNUNET_JSON_Specification ret = {
194 .parser = &parse_variable_data,
195 .cleaner = &clean_variable_data,
210 * Parse given JSON object to string.
212 * @param cls closure, NULL
213 * @param root the json object representing data
214 * @param[out] spec where to write the data
215 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
218 parse_string (void *cls,
220 struct GNUNET_JSON_Specification *spec)
224 str = json_string_value (root);
228 return GNUNET_SYSERR;
230 *(const char **) spec->ptr = str;
236 * The expected field stores a string.
238 * @param name name of the JSON field
239 * @param strptr where to store a pointer to the field
241 struct GNUNET_JSON_Specification
242 GNUNET_JSON_spec_string (const char *name,
245 struct GNUNET_JSON_Specification ret = {
246 .parser = &parse_string,
261 * Parse given JSON object to a JSON object. (Yes, trivial.)
263 * @param cls closure, NULL
264 * @param root the json object representing data
265 * @param[out] spec where to write the data
266 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
269 parse_object (void *cls,
271 struct GNUNET_JSON_Specification *spec)
273 if (! (json_is_object (root) || json_is_array (root)))
276 return GNUNET_SYSERR;
279 *(json_t **) spec->ptr = root;
285 * Cleanup data left from parsing JSON object.
287 * @param cls closure, NULL
288 * @param[out] spec where to free the data
291 clean_object (void *cls,
292 struct GNUNET_JSON_Specification *spec)
294 json_t **ptr = (json_t **) spec->ptr;
307 * @param name name of the JSON field
308 * @param[out] jsonp where to store the JSON found under @a name
310 struct GNUNET_JSON_Specification
311 GNUNET_JSON_spec_json (const char *name,
314 struct GNUNET_JSON_Specification ret = {
315 .parser = &parse_object,
316 .cleaner = &clean_object,
330 * Parse given JSON object to a uint8_t.
332 * @param cls closure, NULL
333 * @param root the json object representing data
334 * @param[out] spec where to write the data
335 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
340 struct GNUNET_JSON_Specification *spec)
343 uint8_t *up = spec->ptr;
345 if (! json_is_integer (root))
348 return GNUNET_SYSERR;
350 val = json_integer_value (root);
351 if ((0 > val) || (val > UINT8_MAX))
354 return GNUNET_SYSERR;
364 * @param name name of the JSON field
365 * @param[out] u8 where to store the integer found under @a name
367 struct GNUNET_JSON_Specification
368 GNUNET_JSON_spec_uint8 (const char *name,
371 struct GNUNET_JSON_Specification ret = {
377 .ptr_size = sizeof(uint8_t),
386 * Parse given JSON object to a uint16_t.
388 * @param cls closure, NULL
389 * @param root the json object representing data
390 * @param[out] spec where to write the data
391 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
394 parse_u16 (void *cls,
396 struct GNUNET_JSON_Specification *spec)
399 uint16_t *up = spec->ptr;
401 if (! json_is_integer (root))
404 return GNUNET_SYSERR;
406 val = json_integer_value (root);
407 if ((0 > val) || (val > UINT16_MAX))
410 return GNUNET_SYSERR;
412 *up = (uint16_t) val;
420 * @param name name of the JSON field
421 * @param[out] u16 where to store the integer found under @a name
423 struct GNUNET_JSON_Specification
424 GNUNET_JSON_spec_uint16 (const char *name,
427 struct GNUNET_JSON_Specification ret = {
428 .parser = &parse_u16,
433 .ptr_size = sizeof(uint16_t),
442 * Parse given JSON object to a uint32_t.
444 * @param cls closure, NULL
445 * @param root the json object representing data
446 * @param[out] spec where to write the data
447 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
450 parse_u32 (void *cls,
452 struct GNUNET_JSON_Specification *spec)
455 uint32_t *up = spec->ptr;
457 if (! json_is_integer (root))
460 return GNUNET_SYSERR;
462 val = json_integer_value (root);
463 if ((0 > val) || (val > UINT32_MAX))
466 return GNUNET_SYSERR;
468 *up = (uint32_t) val;
476 * @param name name of the JSON field
477 * @param[out] u32 where to store the integer found under @a name
479 struct GNUNET_JSON_Specification
480 GNUNET_JSON_spec_uint32 (const char *name,
483 struct GNUNET_JSON_Specification ret = {
484 .parser = &parse_u32,
489 .ptr_size = sizeof(uint32_t),
498 * Parse given JSON object to a uint8_t.
500 * @param cls closure, NULL
501 * @param root the json object representing data
502 * @param[out] spec where to write the data
503 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
506 parse_u64 (void *cls,
508 struct GNUNET_JSON_Specification *spec)
511 uint64_t *up = spec->ptr;
513 if (! json_is_integer (root))
516 return GNUNET_SYSERR;
518 val = json_integer_value (root);
519 *up = (uint64_t) val;
527 * @param name name of the JSON field
528 * @param[out] u64 where to store the integer found under @a name
530 struct GNUNET_JSON_Specification
531 GNUNET_JSON_spec_uint64 (const char *name,
534 struct GNUNET_JSON_Specification ret = {
535 .parser = &parse_u64,
540 .ptr_size = sizeof(uint64_t),
548 /* ************ GNUnet-specific parser specifications ******************* */
551 * Parse given JSON object to absolute time.
553 * @param cls closure, NULL
554 * @param root the json object representing data
555 * @param[out] spec where to write the data
556 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
559 parse_abs_time (void *cls,
561 struct GNUNET_JSON_Specification *spec)
563 struct GNUNET_TIME_Absolute *abs = spec->ptr;
565 unsigned long long int tval;
567 if (! json_is_object (root))
570 return GNUNET_SYSERR;
572 json_t_ms = json_object_get (root, "t_ms");
573 if (json_is_integer (json_t_ms))
575 tval = json_integer_value (json_t_ms);
576 /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
577 abs->abs_value_us = tval * 1000LL;
578 if ((abs->abs_value_us) / 1000LL != tval)
580 /* Integer overflow */
582 return GNUNET_SYSERR;
586 if (json_is_string (json_t_ms))
589 val = json_string_value (json_t_ms);
590 if ((0 == strcasecmp (val, "never")))
592 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
596 return GNUNET_SYSERR;
599 return GNUNET_SYSERR;
606 * @param name name of the JSON field
607 * @param[out] at where to store the absolute time found under @a name
609 struct GNUNET_JSON_Specification
610 GNUNET_JSON_spec_absolute_time (const char *name,
611 struct GNUNET_TIME_Absolute *at)
613 struct GNUNET_JSON_Specification ret = {
614 .parser = &parse_abs_time,
619 .ptr_size = sizeof(uint64_t),
628 * Parse given JSON object to absolute time.
630 * @param cls closure, NULL
631 * @param root the json object representing data
632 * @param[out] spec where to write the data
633 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
636 parse_abs_time_nbo (void *cls,
638 struct GNUNET_JSON_Specification *spec)
640 struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
641 struct GNUNET_TIME_Absolute a;
642 struct GNUNET_JSON_Specification ispec;
645 ispec.parser = &parse_abs_time;
648 parse_abs_time (NULL,
651 return GNUNET_SYSERR;
652 *abs = GNUNET_TIME_absolute_hton (a);
658 * Absolute time in network byte order.
660 * @param name name of the JSON field
661 * @param[out] at where to store the absolute time found under @a name
663 struct GNUNET_JSON_Specification
664 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
665 struct GNUNET_TIME_AbsoluteNBO *at)
667 struct GNUNET_JSON_Specification ret = {
668 .parser = &parse_abs_time_nbo,
673 .ptr_size = sizeof(uint64_t),
682 * Parse given JSON object to relative time.
684 * @param cls closure, NULL
685 * @param root the json object representing data
686 * @param[out] spec where to write the data
687 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
690 parse_rel_time (void *cls,
692 struct GNUNET_JSON_Specification *spec)
694 struct GNUNET_TIME_Relative *rel = spec->ptr;
696 unsigned long long int tval;
698 if (! json_is_object (root))
701 return GNUNET_SYSERR;
703 json_d_ms = json_object_get (root, "d_ms");
704 if (json_is_integer (json_d_ms))
706 tval = json_integer_value (json_d_ms);
707 /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
708 rel->rel_value_us = tval * 1000LL;
709 if ((rel->rel_value_us) / 1000LL != tval)
711 /* Integer overflow */
713 return GNUNET_SYSERR;
717 if (json_is_string (json_d_ms))
720 val = json_string_value (json_d_ms);
721 if ((0 == strcasecmp (val, "forever")))
723 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
727 return GNUNET_SYSERR;
730 return GNUNET_SYSERR;
737 * @param name name of the JSON field
738 * @param[out] rt where to store the relative time found under @a name
740 struct GNUNET_JSON_Specification
741 GNUNET_JSON_spec_relative_time (const char *name,
742 struct GNUNET_TIME_Relative *rt)
744 struct GNUNET_JSON_Specification ret = {
745 .parser = &parse_rel_time,
750 .ptr_size = sizeof(uint64_t),
759 * Parse given JSON object to RSA public key.
761 * @param cls closure, NULL
762 * @param root the json object representing data
763 * @param[out] spec where to write the data
764 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
767 parse_rsa_public_key (void *cls,
769 struct GNUNET_JSON_Specification *spec)
771 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
777 if (NULL == (enc = json_string_value (root)))
780 return GNUNET_SYSERR;
783 buf_len = (len * 5) / 8;
784 buf = GNUNET_malloc (buf_len);
786 GNUNET_STRINGS_string_to_data (enc,
793 return GNUNET_SYSERR;
795 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
800 return GNUNET_SYSERR;
808 * Cleanup data left from parsing RSA public key.
810 * @param cls closure, NULL
811 * @param[out] spec where to free the data
814 clean_rsa_public_key (void *cls,
815 struct GNUNET_JSON_Specification *spec)
817 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
821 GNUNET_CRYPTO_rsa_public_key_free (*pk);
828 * Specification for parsing an RSA public key.
830 * @param name name of the JSON field
831 * @param pk where to store the RSA key found under @a name
833 struct GNUNET_JSON_Specification
834 GNUNET_JSON_spec_rsa_public_key (const char *name,
835 struct GNUNET_CRYPTO_RsaPublicKey **pk)
837 struct GNUNET_JSON_Specification ret = {
838 .parser = &parse_rsa_public_key,
839 .cleaner = &clean_rsa_public_key,
853 * Parse given JSON object to RSA signature.
855 * @param cls closure, NULL
856 * @param root the json object representing data
857 * @param[out] spec where to write the data
858 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
861 parse_rsa_signature (void *cls,
863 struct GNUNET_JSON_Specification *spec)
865 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
871 str = json_string_value (root);
875 return GNUNET_SYSERR;
877 size = (strlen (str) * 5) / 8;
878 buf = GNUNET_malloc (size);
879 res = GNUNET_STRINGS_string_to_data (str,
883 if (GNUNET_OK != res)
887 return GNUNET_SYSERR;
889 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
894 return GNUNET_SYSERR;
902 * Cleanup data left from parsing RSA signature.
904 * @param cls closure, NULL
905 * @param[out] spec where to free the data
908 clean_rsa_signature (void *cls,
909 struct GNUNET_JSON_Specification *spec)
911 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
915 GNUNET_CRYPTO_rsa_signature_free (*sig);
922 * Specification for parsing an RSA signature.
924 * @param name name of the JSON field
925 * @param sig where to store the RSA signature found under @a name
927 struct GNUNET_JSON_Specification
928 GNUNET_JSON_spec_rsa_signature (const char *name,
929 struct GNUNET_CRYPTO_RsaSignature **sig)
931 struct GNUNET_JSON_Specification ret = {
932 .parser = &parse_rsa_signature,
933 .cleaner = &clean_rsa_signature,
947 * Parse given JSON object to an int as a boolean.
949 * @param cls closure, NULL
950 * @param root the json object representing data
951 * @param[out] spec where to write the data
952 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
955 parse_boolean (void *cls,
957 struct GNUNET_JSON_Specification *spec)
961 if (! json_is_boolean (root))
964 return GNUNET_SYSERR;
966 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
972 * Boolean (true mapped to GNUNET_YES, false mapped to GNUNET_NO).
974 * @param name name of the JSON field
975 * @param[out] boolean where to store the boolean found under @a name
977 struct GNUNET_JSON_Specification
978 GNUNET_JSON_spec_boolean (const char *name,
981 struct GNUNET_JSON_Specification ret = {
982 .parser = &parse_boolean,
987 .ptr_size = sizeof(int),
995 /* end of json_helper.c */