adding library for basic JSON conversions
[oweals/gnunet.git] / src / json / json_helper.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4
5   GNUnet is free software; you can redistribute it and/or modify it under the
6   terms of the GNU General Public License as published by the Free Software
7   Foundation; either version 3, or (at your option) any later version.
8
9   GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License along with
14   GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
15 */
16 /**
17  * @file json/json_helper.c
18  * @brief functions to generate specifciations for JSON parsing
19  * @author Florian Dold
20  * @author Benedikt Mueller
21  * @author Christian Grothoff
22  */
23 #include "platform.h"
24 #include "gnunet_json_lib.h"
25
26
27 /**
28  * End of a parser specification.
29  */
30 struct GNUNET_JSON_Specification
31 GNUNET_JSON_spec_end ()
32 {
33   struct GNUNET_JSON_Specification ret = {
34     .parser = NULL,
35     .cleaner = NULL,
36     .cls = NULL
37   };
38   return ret;
39 }
40
41
42 /**
43  * Parse given JSON object to fixed size data
44  *
45  * @param cls closure, NULL
46  * @param root the json object representing data
47  * @param[out] spec where to write the data
48  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
49  */
50 static int
51 parse_fixed_data (void *cls,
52                   json_t *root,
53                   struct GNUNET_JSON_Specification *spec)
54 {
55   const char *enc;
56   unsigned int len;
57
58   if (NULL == (enc = json_string_value (root)))
59   {
60     GNUNET_break_op (0);
61     return GNUNET_SYSERR;
62   }
63   len = strlen (enc);
64   if (((len * 5) / 8) != spec->ptr_size)
65   {
66     GNUNET_break_op (0);
67     return GNUNET_SYSERR;
68   }
69   if (GNUNET_OK !=
70       GNUNET_STRINGS_string_to_data (enc,
71                                      len,
72                                      spec->ptr,
73                                      spec->ptr_size))
74   {
75     GNUNET_break_op (0);
76     return GNUNET_SYSERR;
77   }
78   return GNUNET_OK;
79 }
80
81
82 /**
83  * Variable size object (in network byte order, encoded using Crockford
84  * Base32hex encoding).
85  *
86  * @param name name of the JSON field
87  * @param[out] obj pointer where to write the data, must have @a size bytes
88  * @param size number of bytes expected in @a obj
89  */
90 struct GNUNET_JSON_Specification
91 GNUNET_JSON_spec_fixed (const char *name,
92                         void *obj,
93                         size_t size)
94 {
95   struct GNUNET_JSON_Specification ret = {
96     .parser = &parse_fixed_data,
97     .cleaner = NULL,
98     .cls = NULL,
99     .field = name,
100     .ptr = obj,
101     .ptr_size = size,
102     .size_ptr = NULL
103   };
104   return ret;
105 }
106
107
108 /**
109  * Parse given JSON object to variable size data
110  *
111  * @param cls closure, NULL
112  * @param root the json object representing data
113  * @param[out] spec where to write the data
114  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
115  */
116 static int
117 parse_variable_data (void *cls,
118                      json_t *root,
119                      struct GNUNET_JSON_Specification *spec)
120 {
121   const char *str;
122   size_t size;
123   void *data;
124   int res;
125
126   str = json_string_value (root);
127   if (NULL == str)
128   {
129     GNUNET_break_op (0);
130     return GNUNET_SYSERR;
131   }
132   size = (strlen (str) * 5) / 8;
133   if (size >= 1024)
134   {
135     GNUNET_break_op (0);
136     return GNUNET_SYSERR;
137   }
138   data = GNUNET_malloc (size);
139   res = GNUNET_STRINGS_string_to_data (str,
140                                        strlen (str),
141                                        data,
142                                        size);
143   if (GNUNET_OK != res)
144   {
145     GNUNET_break_op (0);
146     GNUNET_free (data);
147     return GNUNET_SYSERR;
148   }
149   *(void**) spec->ptr = data;
150   *spec->size_ptr = size;
151   return GNUNET_OK;
152 }
153
154
155 /**
156  * Cleanup data left from parsing variable size data
157  *
158  * @param cls closure, NULL
159  * @param[out] spec where to free the data
160  */
161 static void
162 clean_variable_data (void *cls,
163                      struct GNUNET_JSON_Specification *spec)
164 {
165   if (0 != *spec->size_ptr)
166   {
167     GNUNET_free (*(void **) spec->ptr);
168     *(void**) spec->ptr = NULL;
169     *spec->size_ptr = 0;
170   }
171 }
172
173
174 /**
175  * Variable size object (in network byte order, encoded using
176  * Crockford Base32hex encoding).
177  *
178  * @param name name of the JSON field
179  * @param[out] obj pointer where to write the data, will be allocated
180  * @param[out] size where to store the number of bytes allocated for @a obj
181  */
182 struct GNUNET_JSON_Specification
183 GNUNET_JSON_spec_varsize (const char *name,
184                           void **obj,
185                           size_t *size)
186 {
187   struct GNUNET_JSON_Specification ret = {
188     .parser = &parse_variable_data,
189     .cleaner = &clean_variable_data,
190     .cls = NULL,
191     .field = name,
192     .ptr = obj,
193     .ptr_size = 0,
194     .size_ptr = size
195   };
196   *obj = NULL;
197   *size = 0;
198   return ret;
199 }
200
201
202 /**
203  * Parse given JSON object to string.
204  *
205  * @param cls closure, NULL
206  * @param root the json object representing data
207  * @param[out] spec where to write the data
208  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
209  */
210 static int
211 parse_string (void *cls,
212               json_t *root,
213               struct GNUNET_JSON_Specification *spec)
214 {
215   const char *str;
216
217   str = json_string_value (root);
218   if (NULL == str)
219   {
220     GNUNET_break_op (0);
221     return GNUNET_SYSERR;
222   }
223   *(const char **) spec->ptr = str;
224   return GNUNET_OK;
225 }
226
227
228 /**
229  * The expected field stores a string.
230  *
231  * @param name name of the JSON field
232  * @param strptr where to store a pointer to the field
233  */
234 struct GNUNET_JSON_Specification
235 GNUNET_JSON_spec_string (const char *name,
236                          const char **strptr)
237 {
238   struct GNUNET_JSON_Specification ret = {
239     .parser = &parse_string,
240     .cleaner = NULL,
241     .cls = NULL,
242     .field = name,
243     .ptr = strptr,
244     .ptr_size = 0,
245     .size_ptr = NULL
246   };
247   return ret;
248 }
249
250
251 /**
252  * Parse given JSON object to a JSON object. (Yes, trivial.)
253  *
254  * @param cls closure, NULL
255  * @param root the json object representing data
256  * @param[out] spec where to write the data
257  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
258  */
259 static int
260 parse_object (void *cls,
261               json_t *root,
262               struct GNUNET_JSON_Specification *spec)
263 {
264   if (! (json_is_object (root) || json_is_array (root)) )
265   {
266     GNUNET_break_op (0);
267     return GNUNET_SYSERR;
268   }
269   json_incref (root);
270   *(json_t **) spec->ptr = root;
271   return GNUNET_OK;
272 }
273
274
275 /**
276  * Cleanup data left from parsing JSON object.
277  *
278  * @param cls closure, NULL
279  * @param[out] spec where to free the data
280  */
281 static void
282 clean_object (void *cls,
283               struct GNUNET_JSON_Specification *spec)
284 {
285   json_t **ptr = (json_t **) spec->ptr;
286   if (NULL != *ptr)
287   {
288     json_decref (*ptr);
289     *ptr = NULL;
290   }
291 }
292
293
294 /**
295  * JSON object.
296  *
297  * @param name name of the JSON field
298  * @param[out] jsonp where to store the JSON found under @a name
299  */
300 struct GNUNET_JSON_Specification
301 GNUNET_JSON_spec_json (const char *name,
302                        json_t **jsonp)
303 {
304   struct GNUNET_JSON_Specification ret = {
305     .parser = &parse_object,
306     .cleaner = &clean_object,
307     .cls = NULL,
308     .field = name,
309     .ptr = jsonp,
310     .ptr_size = 0,
311     .size_ptr = NULL
312   };
313   return ret;
314 }
315
316
317 /**
318  * Parse given JSON object to a uint8_t.
319  *
320  * @param cls closure, NULL
321  * @param root the json object representing data
322  * @param[out] spec where to write the data
323  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
324  */
325 static int
326 parse_u8 (void *cls,
327           json_t *root,
328           struct GNUNET_JSON_Specification *spec)
329 {
330   json_int_t val;
331   uint8_t *up = spec->ptr;
332
333   if (! json_is_integer (root))
334   {
335     GNUNET_break_op (0);
336     return GNUNET_SYSERR;
337   }
338   val = json_integer_value (root);
339   if ( (0 > val) || (val > UINT8_MAX) )
340   {
341     GNUNET_break_op (0);
342     return GNUNET_SYSERR;
343   }
344   *up = (uint8_t) val;
345   return GNUNET_OK;
346 }
347
348
349 /**
350  * 8-bit integer.
351  *
352  * @param name name of the JSON field
353  * @param[out] u8 where to store the integer found under @a name
354  */
355 struct GNUNET_JSON_Specification
356 GNUNET_JSON_spec_uint8 (const char *name,
357                         uint8_t *u8)
358 {
359   struct GNUNET_JSON_Specification ret = {
360     .parser = &parse_u8,
361     .cleaner = NULL,
362     .cls = NULL,
363     .field = name,
364     .ptr = u8,
365     .ptr_size = sizeof (uint8_t),
366     .size_ptr = NULL
367   };
368   return ret;
369 }
370
371
372 /**
373  * Parse given JSON object to a uint16_t.
374  *
375  * @param cls closure, NULL
376  * @param root the json object representing data
377  * @param[out] spec where to write the data
378  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
379  */
380 static int
381 parse_u16 (void *cls,
382            json_t *root,
383            struct GNUNET_JSON_Specification *spec)
384 {
385   json_int_t val;
386   uint16_t *up = spec->ptr;
387
388   if (! json_is_integer (root))
389   {
390     GNUNET_break_op (0);
391     return GNUNET_SYSERR;
392   }
393   val = json_integer_value (root);
394   if ( (0 > val) || (val > UINT16_MAX) )
395   {
396     GNUNET_break_op (0);
397     return GNUNET_SYSERR;
398   }
399   *up = (uint16_t) val;
400   return GNUNET_OK;
401 }
402
403
404 /**
405  * 16-bit integer.
406  *
407  * @param name name of the JSON field
408  * @param[out] u16 where to store the integer found under @a name
409  */
410 struct GNUNET_JSON_Specification
411 GNUNET_JSON_spec_uint16 (const char *name,
412                          uint16_t *u16)
413 {
414   struct GNUNET_JSON_Specification ret = {
415     .parser = &parse_u16,
416     .cleaner = NULL,
417     .cls = NULL,
418     .field = name,
419     .ptr = u16,
420     .ptr_size = sizeof (uint16_t),
421     .size_ptr = NULL
422   };
423   return ret;
424 }
425
426
427 /**
428  * Parse given JSON object to a uint32_t.
429  *
430  * @param cls closure, NULL
431  * @param root the json object representing data
432  * @param[out] spec where to write the data
433  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
434  */
435 static int
436 parse_u32 (void *cls,
437            json_t *root,
438            struct GNUNET_JSON_Specification *spec)
439 {
440   json_int_t val;
441   uint32_t *up = spec->ptr;
442
443   if (! json_is_integer (root))
444   {
445     GNUNET_break_op (0);
446     return GNUNET_SYSERR;
447   }
448   val = json_integer_value (root);
449   if ( (0 > val) || (val > UINT32_MAX) )
450   {
451     GNUNET_break_op (0);
452     return GNUNET_SYSERR;
453   }
454   *up = (uint32_t) val;
455   return GNUNET_OK;
456 }
457
458
459 /**
460  * 32-bit integer.
461  *
462  * @param name name of the JSON field
463  * @param[out] u32 where to store the integer found under @a name
464  */
465 struct GNUNET_JSON_Specification
466 GNUNET_JSON_spec_uint32 (const char *name,
467                          uint32_t *u32)
468 {
469   struct GNUNET_JSON_Specification ret = {
470     .parser = &parse_u32,
471     .cleaner = NULL,
472     .cls = NULL,
473     .field = name,
474     .ptr = u32,
475     .ptr_size = sizeof (uint32_t),
476     .size_ptr = NULL
477   };
478   return ret;
479 }
480
481
482 /**
483  * Parse given JSON object to a uint8_t.
484  *
485  * @param cls closure, NULL
486  * @param root the json object representing data
487  * @param[out] spec where to write the data
488  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
489  */
490 static int
491 parse_u64 (void *cls,
492            json_t *root,
493            struct GNUNET_JSON_Specification *spec)
494 {
495   json_int_t val;
496   uint64_t *up = spec->ptr;
497
498   if (! json_is_integer (root))
499   {
500     GNUNET_break_op (0);
501     return GNUNET_SYSERR;
502   }
503   val = json_integer_value (root);
504   *up = (uint64_t) val;
505   return GNUNET_OK;
506 }
507
508
509 /**
510  * 64-bit integer.
511  *
512  * @param name name of the JSON field
513  * @param[out] u64 where to store the integer found under @a name
514  */
515 struct GNUNET_JSON_Specification
516 GNUNET_JSON_spec_uint64 (const char *name,
517                          uint64_t *u64)
518 {
519   struct GNUNET_JSON_Specification ret = {
520     .parser = &parse_u64,
521     .cleaner = NULL,
522     .cls = NULL,
523     .field = name,
524     .ptr = u64,
525     .ptr_size = sizeof (uint64_t),
526     .size_ptr = NULL
527   };
528   return ret;
529 }
530
531
532 /* ************ GNUnet-specific parser specifications ******************* */
533
534 /**
535  * Parse given JSON object to absolute time.
536  *
537  * @param cls closure, NULL
538  * @param root the json object representing data
539  * @param[out] spec where to write the data
540  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
541  */
542 static int
543 parse_abs_time (void *cls,
544                 json_t *root,
545                 struct GNUNET_JSON_Specification *spec)
546 {
547   struct GNUNET_TIME_Absolute *abs = spec->ptr;
548   const char *val;
549   unsigned long long int tval;
550
551   val = json_string_value (root);
552   if (NULL == val)
553   {
554     GNUNET_break_op (0);
555     return GNUNET_SYSERR;
556   }
557   if ( (0 == strcasecmp (val,
558                          "/forever/")) ||
559        (0 == strcasecmp (val,
560                          "/end of time/")) ||
561        (0 == strcasecmp (val,
562                          "/never/")) )
563   {
564     *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
565     return GNUNET_OK;
566   }
567   if (1 != sscanf (val,
568                    "/Date(%llu)/",
569                    &tval))
570   {
571     GNUNET_break_op (0);
572     return GNUNET_SYSERR;
573   }
574   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
575   abs->abs_value_us = tval * 1000LL * 1000LL;
576   if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
577   {
578     /* Integer overflow */
579     GNUNET_break_op (0);
580     return GNUNET_SYSERR;
581   }
582   return GNUNET_OK;
583 }
584
585
586 /**
587  * Absolute time.
588  *
589  * @param name name of the JSON field
590  * @param[out] at where to store the absolute time found under @a name
591  */
592 struct GNUNET_JSON_Specification
593 GNUNET_JSON_spec_absolute_time (const char *name,
594                                 struct GNUNET_TIME_Absolute *at)
595 {
596   struct GNUNET_JSON_Specification ret = {
597     .parser = &parse_abs_time,
598     .cleaner = NULL,
599     .cls = NULL,
600     .field = name,
601     .ptr = at,
602     .ptr_size = sizeof (uint64_t),
603     .size_ptr = NULL
604   };
605   return ret;
606 }
607
608
609 /**
610  * Parse given JSON object to relative time.
611  *
612  * @param cls closure, NULL
613  * @param root the json object representing data
614  * @param[out] spec where to write the data
615  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
616  */
617 static int
618 parse_rel_time (void *cls,
619                 json_t *root,
620                 struct GNUNET_JSON_Specification *spec)
621 {
622   struct GNUNET_TIME_Relative *rel = spec->ptr;
623   const char *val;
624   unsigned long long int tval;
625
626   val = json_string_value (root);
627   if (NULL == val)
628   {
629     GNUNET_break_op (0);
630     return GNUNET_SYSERR;
631   }
632   if ( (0 == strcasecmp (val,
633                          "/forever/")) )
634   {
635     *rel = GNUNET_TIME_UNIT_FOREVER_REL;
636     return GNUNET_OK;
637   }
638   if (1 != sscanf (val,
639                    "/Delay(%llu)/",
640                    &tval))
641   {
642     GNUNET_break_op (0);
643     return GNUNET_SYSERR;
644   }
645   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
646   rel->rel_value_us = tval * 1000LL * 1000LL;
647   if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
648   {
649     /* Integer overflow */
650     GNUNET_break_op (0);
651     return GNUNET_SYSERR;
652   }
653   return GNUNET_OK;
654 }
655
656
657 /**
658  * Relative time.
659  *
660  * @param name name of the JSON field
661  * @param[out] rt where to store the relative time found under @a name
662  */
663 struct GNUNET_JSON_Specification
664 GNUNET_JSON_spec_relative_time (const char *name,
665                                 struct GNUNET_TIME_Relative *rt)
666 {
667   struct GNUNET_JSON_Specification ret = {
668     .parser = &parse_rel_time,
669     .cleaner = NULL,
670     .cls = NULL,
671     .field = name,
672     .ptr = rt,
673     .ptr_size = sizeof (uint64_t),
674     .size_ptr = NULL
675   };
676   return ret;
677 }
678
679
680 /**
681  * Parse given JSON object to RSA public key.
682  *
683  * @param cls closure, NULL
684  * @param root the json object representing data
685  * @param[out] spec where to write the data
686  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
687  */
688 static int
689 parse_rsa_public_key (void *cls,
690                       json_t *root,
691                       struct GNUNET_JSON_Specification *spec)
692 {
693   struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
694   const char *enc;
695   char *buf;
696   size_t len;
697   size_t buf_len;
698
699   if (NULL == (enc = json_string_value (root)))
700   {
701     GNUNET_break_op (0);
702     return GNUNET_SYSERR;
703   }
704   len = strlen (enc);
705   buf_len =  (len * 5) / 8;
706   buf = GNUNET_malloc (buf_len);
707   if (GNUNET_OK !=
708       GNUNET_STRINGS_string_to_data (enc,
709                                      len,
710                                      buf,
711                                      buf_len))
712   {
713     GNUNET_break_op (0);
714     GNUNET_free (buf);
715     return GNUNET_SYSERR;
716   }
717   if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
718                                                           buf_len)))
719   {
720     GNUNET_break_op (0);
721     GNUNET_free (buf);
722     return GNUNET_SYSERR;
723   }
724   GNUNET_free (buf);
725   return GNUNET_OK;
726 }
727
728
729 /**
730  * Cleanup data left from parsing RSA public key.
731  *
732  * @param cls closure, NULL
733  * @param[out] spec where to free the data
734  */
735 static void
736 clean_rsa_public_key (void *cls,
737                       struct GNUNET_JSON_Specification *spec)
738 {
739   struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
740
741   if (NULL != *pk)
742   {
743     GNUNET_CRYPTO_rsa_public_key_free (*pk);
744     *pk = NULL;
745   }
746 }
747
748
749 /**
750  * Specification for parsing an RSA public key.
751  *
752  * @param name name of the JSON field
753  * @param pk where to store the RSA key found under @a name
754  */
755 struct GNUNET_JSON_Specification
756 GNUNET_JSON_spec_rsa_public_key (const char *name,
757                                  struct GNUNET_CRYPTO_rsa_PublicKey **pk)
758 {
759   struct GNUNET_JSON_Specification ret = {
760     .parser = &parse_rsa_public_key,
761     .cleaner = &clean_rsa_public_key,
762     .cls = NULL,
763     .field = name,
764     .ptr = pk,
765     .ptr_size = 0,
766     .size_ptr = NULL
767   };
768   return ret;
769 }
770
771
772 /**
773  * Parse given JSON object to RSA signature.
774  *
775  * @param cls closure, NULL
776  * @param root the json object representing data
777  * @param[out] spec where to write the data
778  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
779  */
780 static int
781 parse_rsa_signature (void *cls,
782                      json_t *root,
783                      struct GNUNET_JSON_Specification *spec)
784 {
785   struct GNUNET_CRYPTO_rsa_Signature **sig = spec->ptr;
786   size_t size;
787   const char *str;
788   int res;
789   void *buf;
790
791   str = json_string_value (root);
792   if (NULL == str)
793   {
794     GNUNET_break_op (0);
795     return GNUNET_SYSERR;
796   }
797   size = (strlen (str) * 5) / 8;
798   buf = GNUNET_malloc (size);
799   res = GNUNET_STRINGS_string_to_data (str,
800                                        strlen (str),
801                                        buf,
802                                        size);
803   if (GNUNET_OK != res)
804   {
805     GNUNET_free (buf);
806     GNUNET_break_op (0);
807     return GNUNET_SYSERR;
808   }
809   if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
810                                                           size)))
811   {
812     GNUNET_break_op (0);
813     GNUNET_free (buf);
814     return GNUNET_SYSERR;
815   }
816   GNUNET_free (buf);
817   return GNUNET_OK;
818 }
819
820
821 /**
822  * Cleanup data left from parsing RSA signature.
823  *
824  * @param cls closure, NULL
825  * @param[out] spec where to free the data
826  */
827 static void
828 clean_rsa_signature (void *cls,
829                      struct GNUNET_JSON_Specification *spec)
830 {
831   struct GNUNET_CRYPTO_rsa_Signature  **sig = spec->ptr;
832
833   if (NULL != *sig)
834   {
835     GNUNET_CRYPTO_rsa_signature_free (*sig);
836     *sig = NULL;
837   }
838 }
839
840
841 /**
842  * Specification for parsing an RSA signature.
843  *
844  * @param name name of the JSON field
845  * @param sig where to store the RSA signature found under @a name
846  */
847 struct GNUNET_JSON_Specification
848 GNUNET_JSON_spec_rsa_signature (const char *name,
849                                 struct GNUNET_CRYPTO_rsa_Signature **sig)
850 {
851   struct GNUNET_JSON_Specification ret = {
852     .parser = &parse_rsa_signature,
853     .cleaner = &clean_rsa_signature,
854     .cls = NULL,
855     .field = name,
856     .ptr = sig,
857     .ptr_size = 0,
858     .size_ptr = NULL
859   };
860   return ret;
861 }
862
863
864 /* end of json_helper.c */