[datastore] Combine put and update plugin APIs
[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   *strptr = NULL;
248   return ret;
249 }
250
251
252 /**
253  * Parse given JSON object to a JSON object. (Yes, trivial.)
254  *
255  * @param cls closure, NULL
256  * @param root the json object representing data
257  * @param[out] spec where to write the data
258  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
259  */
260 static int
261 parse_object (void *cls,
262               json_t *root,
263               struct GNUNET_JSON_Specification *spec)
264 {
265   if (! (json_is_object (root) || json_is_array (root)) )
266   {
267     GNUNET_break_op (0);
268     return GNUNET_SYSERR;
269   }
270   json_incref (root);
271   *(json_t **) spec->ptr = root;
272   return GNUNET_OK;
273 }
274
275
276 /**
277  * Cleanup data left from parsing JSON object.
278  *
279  * @param cls closure, NULL
280  * @param[out] spec where to free the data
281  */
282 static void
283 clean_object (void *cls,
284               struct GNUNET_JSON_Specification *spec)
285 {
286   json_t **ptr = (json_t **) spec->ptr;
287
288   if (NULL != *ptr)
289   {
290     json_decref (*ptr);
291     *ptr = NULL;
292   }
293 }
294
295
296 /**
297  * JSON object.
298  *
299  * @param name name of the JSON field
300  * @param[out] jsonp where to store the JSON found under @a name
301  */
302 struct GNUNET_JSON_Specification
303 GNUNET_JSON_spec_json (const char *name,
304                        json_t **jsonp)
305 {
306   struct GNUNET_JSON_Specification ret = {
307     .parser = &parse_object,
308     .cleaner = &clean_object,
309     .cls = NULL,
310     .field = name,
311     .ptr = jsonp,
312     .ptr_size = 0,
313     .size_ptr = NULL
314   };
315   *jsonp = NULL;
316   return ret;
317 }
318
319
320 /**
321  * Parse given JSON object to a uint8_t.
322  *
323  * @param cls closure, NULL
324  * @param root the json object representing data
325  * @param[out] spec where to write the data
326  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
327  */
328 static int
329 parse_u8 (void *cls,
330           json_t *root,
331           struct GNUNET_JSON_Specification *spec)
332 {
333   json_int_t val;
334   uint8_t *up = spec->ptr;
335
336   if (! json_is_integer (root))
337   {
338     GNUNET_break_op (0);
339     return GNUNET_SYSERR;
340   }
341   val = json_integer_value (root);
342   if ( (0 > val) || (val > UINT8_MAX) )
343   {
344     GNUNET_break_op (0);
345     return GNUNET_SYSERR;
346   }
347   *up = (uint8_t) val;
348   return GNUNET_OK;
349 }
350
351
352 /**
353  * 8-bit integer.
354  *
355  * @param name name of the JSON field
356  * @param[out] u8 where to store the integer found under @a name
357  */
358 struct GNUNET_JSON_Specification
359 GNUNET_JSON_spec_uint8 (const char *name,
360                         uint8_t *u8)
361 {
362   struct GNUNET_JSON_Specification ret = {
363     .parser = &parse_u8,
364     .cleaner = NULL,
365     .cls = NULL,
366     .field = name,
367     .ptr = u8,
368     .ptr_size = sizeof (uint8_t),
369     .size_ptr = NULL
370   };
371   return ret;
372 }
373
374
375 /**
376  * Parse given JSON object to a uint16_t.
377  *
378  * @param cls closure, NULL
379  * @param root the json object representing data
380  * @param[out] spec where to write the data
381  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
382  */
383 static int
384 parse_u16 (void *cls,
385            json_t *root,
386            struct GNUNET_JSON_Specification *spec)
387 {
388   json_int_t val;
389   uint16_t *up = spec->ptr;
390
391   if (! json_is_integer (root))
392   {
393     GNUNET_break_op (0);
394     return GNUNET_SYSERR;
395   }
396   val = json_integer_value (root);
397   if ( (0 > val) || (val > UINT16_MAX) )
398   {
399     GNUNET_break_op (0);
400     return GNUNET_SYSERR;
401   }
402   *up = (uint16_t) val;
403   return GNUNET_OK;
404 }
405
406
407 /**
408  * 16-bit integer.
409  *
410  * @param name name of the JSON field
411  * @param[out] u16 where to store the integer found under @a name
412  */
413 struct GNUNET_JSON_Specification
414 GNUNET_JSON_spec_uint16 (const char *name,
415                          uint16_t *u16)
416 {
417   struct GNUNET_JSON_Specification ret = {
418     .parser = &parse_u16,
419     .cleaner = NULL,
420     .cls = NULL,
421     .field = name,
422     .ptr = u16,
423     .ptr_size = sizeof (uint16_t),
424     .size_ptr = NULL
425   };
426   return ret;
427 }
428
429
430 /**
431  * Parse given JSON object to a uint32_t.
432  *
433  * @param cls closure, NULL
434  * @param root the json object representing data
435  * @param[out] spec where to write the data
436  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
437  */
438 static int
439 parse_u32 (void *cls,
440            json_t *root,
441            struct GNUNET_JSON_Specification *spec)
442 {
443   json_int_t val;
444   uint32_t *up = spec->ptr;
445
446   if (! json_is_integer (root))
447   {
448     GNUNET_break_op (0);
449     return GNUNET_SYSERR;
450   }
451   val = json_integer_value (root);
452   if ( (0 > val) || (val > UINT32_MAX) )
453   {
454     GNUNET_break_op (0);
455     return GNUNET_SYSERR;
456   }
457   *up = (uint32_t) val;
458   return GNUNET_OK;
459 }
460
461
462 /**
463  * 32-bit integer.
464  *
465  * @param name name of the JSON field
466  * @param[out] u32 where to store the integer found under @a name
467  */
468 struct GNUNET_JSON_Specification
469 GNUNET_JSON_spec_uint32 (const char *name,
470                          uint32_t *u32)
471 {
472   struct GNUNET_JSON_Specification ret = {
473     .parser = &parse_u32,
474     .cleaner = NULL,
475     .cls = NULL,
476     .field = name,
477     .ptr = u32,
478     .ptr_size = sizeof (uint32_t),
479     .size_ptr = NULL
480   };
481   return ret;
482 }
483
484
485 /**
486  * Parse given JSON object to a uint8_t.
487  *
488  * @param cls closure, NULL
489  * @param root the json object representing data
490  * @param[out] spec where to write the data
491  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
492  */
493 static int
494 parse_u64 (void *cls,
495            json_t *root,
496            struct GNUNET_JSON_Specification *spec)
497 {
498   json_int_t val;
499   uint64_t *up = spec->ptr;
500
501   if (! json_is_integer (root))
502   {
503     GNUNET_break_op (0);
504     return GNUNET_SYSERR;
505   }
506   val = json_integer_value (root);
507   *up = (uint64_t) val;
508   return GNUNET_OK;
509 }
510
511
512 /**
513  * 64-bit integer.
514  *
515  * @param name name of the JSON field
516  * @param[out] u64 where to store the integer found under @a name
517  */
518 struct GNUNET_JSON_Specification
519 GNUNET_JSON_spec_uint64 (const char *name,
520                          uint64_t *u64)
521 {
522   struct GNUNET_JSON_Specification ret = {
523     .parser = &parse_u64,
524     .cleaner = NULL,
525     .cls = NULL,
526     .field = name,
527     .ptr = u64,
528     .ptr_size = sizeof (uint64_t),
529     .size_ptr = NULL
530   };
531   return ret;
532 }
533
534
535 /* ************ GNUnet-specific parser specifications ******************* */
536
537 /**
538  * Parse given JSON object to absolute time.
539  *
540  * @param cls closure, NULL
541  * @param root the json object representing data
542  * @param[out] spec where to write the data
543  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
544  */
545 static int
546 parse_abs_time (void *cls,
547                 json_t *root,
548                 struct GNUNET_JSON_Specification *spec)
549 {
550   struct GNUNET_TIME_Absolute *abs = spec->ptr;
551   const char *val;
552   unsigned long long int tval;
553
554   val = json_string_value (root);
555   if (NULL == val)
556   {
557     GNUNET_break_op (0);
558     return GNUNET_SYSERR;
559   }
560   if ( (0 == strcasecmp (val,
561                          "/forever/")) ||
562        (0 == strcasecmp (val,
563                          "/end of time/")) ||
564        (0 == strcasecmp (val,
565                          "/never/")) )
566   {
567     *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
568     return GNUNET_OK;
569   }
570   if (1 != sscanf (val,
571                    "/Date(%llu)/",
572                    &tval))
573   {
574     GNUNET_break_op (0);
575     return GNUNET_SYSERR;
576   }
577   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
578   abs->abs_value_us = tval * 1000LL * 1000LL;
579   if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
580   {
581     /* Integer overflow */
582     GNUNET_break_op (0);
583     return GNUNET_SYSERR;
584   }
585   return GNUNET_OK;
586 }
587
588
589 /**
590  * Absolute time.
591  *
592  * @param name name of the JSON field
593  * @param[out] at where to store the absolute time found under @a name
594  */
595 struct GNUNET_JSON_Specification
596 GNUNET_JSON_spec_absolute_time (const char *name,
597                                 struct GNUNET_TIME_Absolute *at)
598 {
599   struct GNUNET_JSON_Specification ret = {
600     .parser = &parse_abs_time,
601     .cleaner = NULL,
602     .cls = NULL,
603     .field = name,
604     .ptr = at,
605     .ptr_size = sizeof (uint64_t),
606     .size_ptr = NULL
607   };
608   return ret;
609 }
610
611
612 /**
613  * Parse given JSON object to relative time.
614  *
615  * @param cls closure, NULL
616  * @param root the json object representing data
617  * @param[out] spec where to write the data
618  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
619  */
620 static int
621 parse_rel_time (void *cls,
622                 json_t *root,
623                 struct GNUNET_JSON_Specification *spec)
624 {
625   struct GNUNET_TIME_Relative *rel = spec->ptr;
626   const char *val;
627   unsigned long long int tval;
628
629   val = json_string_value (root);
630   if (NULL == val)
631   {
632     GNUNET_break_op (0);
633     return GNUNET_SYSERR;
634   }
635   if ( (0 == strcasecmp (val,
636                          "/forever/")) )
637   {
638     *rel = GNUNET_TIME_UNIT_FOREVER_REL;
639     return GNUNET_OK;
640   }
641   if (1 != sscanf (val,
642                    "/Delay(%llu)/",
643                    &tval))
644   {
645     GNUNET_break_op (0);
646     return GNUNET_SYSERR;
647   }
648   /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
649   rel->rel_value_us = tval * 1000LL * 1000LL;
650   if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
651   {
652     /* Integer overflow */
653     GNUNET_break_op (0);
654     return GNUNET_SYSERR;
655   }
656   return GNUNET_OK;
657 }
658
659
660 /**
661  * Relative time.
662  *
663  * @param name name of the JSON field
664  * @param[out] rt where to store the relative time found under @a name
665  */
666 struct GNUNET_JSON_Specification
667 GNUNET_JSON_spec_relative_time (const char *name,
668                                 struct GNUNET_TIME_Relative *rt)
669 {
670   struct GNUNET_JSON_Specification ret = {
671     .parser = &parse_rel_time,
672     .cleaner = NULL,
673     .cls = NULL,
674     .field = name,
675     .ptr = rt,
676     .ptr_size = sizeof (uint64_t),
677     .size_ptr = NULL
678   };
679   return ret;
680 }
681
682
683 /**
684  * Parse given JSON object to RSA public key.
685  *
686  * @param cls closure, NULL
687  * @param root the json object representing data
688  * @param[out] spec where to write the data
689  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
690  */
691 static int
692 parse_rsa_public_key (void *cls,
693                       json_t *root,
694                       struct GNUNET_JSON_Specification *spec)
695 {
696   struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
697   const char *enc;
698   char *buf;
699   size_t len;
700   size_t buf_len;
701
702   if (NULL == (enc = json_string_value (root)))
703   {
704     GNUNET_break_op (0);
705     return GNUNET_SYSERR;
706   }
707   len = strlen (enc);
708   buf_len =  (len * 5) / 8;
709   buf = GNUNET_malloc (buf_len);
710   if (GNUNET_OK !=
711       GNUNET_STRINGS_string_to_data (enc,
712                                      len,
713                                      buf,
714                                      buf_len))
715   {
716     GNUNET_break_op (0);
717     GNUNET_free (buf);
718     return GNUNET_SYSERR;
719   }
720   if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
721                                                           buf_len)))
722   {
723     GNUNET_break_op (0);
724     GNUNET_free (buf);
725     return GNUNET_SYSERR;
726   }
727   GNUNET_free (buf);
728   return GNUNET_OK;
729 }
730
731
732 /**
733  * Cleanup data left from parsing RSA public key.
734  *
735  * @param cls closure, NULL
736  * @param[out] spec where to free the data
737  */
738 static void
739 clean_rsa_public_key (void *cls,
740                       struct GNUNET_JSON_Specification *spec)
741 {
742   struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
743
744   if (NULL != *pk)
745   {
746     GNUNET_CRYPTO_rsa_public_key_free (*pk);
747     *pk = NULL;
748   }
749 }
750
751
752 /**
753  * Specification for parsing an RSA public key.
754  *
755  * @param name name of the JSON field
756  * @param pk where to store the RSA key found under @a name
757  */
758 struct GNUNET_JSON_Specification
759 GNUNET_JSON_spec_rsa_public_key (const char *name,
760                                  struct GNUNET_CRYPTO_RsaPublicKey **pk)
761 {
762   struct GNUNET_JSON_Specification ret = {
763     .parser = &parse_rsa_public_key,
764     .cleaner = &clean_rsa_public_key,
765     .cls = NULL,
766     .field = name,
767     .ptr = pk,
768     .ptr_size = 0,
769     .size_ptr = NULL
770   };
771   *pk = NULL;
772   return ret;
773 }
774
775
776 /**
777  * Parse given JSON object to RSA signature.
778  *
779  * @param cls closure, NULL
780  * @param root the json object representing data
781  * @param[out] spec where to write the data
782  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
783  */
784 static int
785 parse_rsa_signature (void *cls,
786                      json_t *root,
787                      struct GNUNET_JSON_Specification *spec)
788 {
789   struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
790   size_t size;
791   const char *str;
792   int res;
793   void *buf;
794
795   str = json_string_value (root);
796   if (NULL == str)
797   {
798     GNUNET_break_op (0);
799     return GNUNET_SYSERR;
800   }
801   size = (strlen (str) * 5) / 8;
802   buf = GNUNET_malloc (size);
803   res = GNUNET_STRINGS_string_to_data (str,
804                                        strlen (str),
805                                        buf,
806                                        size);
807   if (GNUNET_OK != res)
808   {
809     GNUNET_free (buf);
810     GNUNET_break_op (0);
811     return GNUNET_SYSERR;
812   }
813   if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
814                                                           size)))
815   {
816     GNUNET_break_op (0);
817     GNUNET_free (buf);
818     return GNUNET_SYSERR;
819   }
820   GNUNET_free (buf);
821   return GNUNET_OK;
822 }
823
824
825 /**
826  * Cleanup data left from parsing RSA signature.
827  *
828  * @param cls closure, NULL
829  * @param[out] spec where to free the data
830  */
831 static void
832 clean_rsa_signature (void *cls,
833                      struct GNUNET_JSON_Specification *spec)
834 {
835   struct GNUNET_CRYPTO_RsaSignature  **sig = spec->ptr;
836
837   if (NULL != *sig)
838   {
839     GNUNET_CRYPTO_rsa_signature_free (*sig);
840     *sig = NULL;
841   }
842 }
843
844
845 /**
846  * Specification for parsing an RSA signature.
847  *
848  * @param name name of the JSON field
849  * @param sig where to store the RSA signature found under @a name
850  */
851 struct GNUNET_JSON_Specification
852 GNUNET_JSON_spec_rsa_signature (const char *name,
853                                 struct GNUNET_CRYPTO_RsaSignature **sig)
854 {
855   struct GNUNET_JSON_Specification ret = {
856     .parser = &parse_rsa_signature,
857     .cleaner = &clean_rsa_signature,
858     .cls = NULL,
859     .field = name,
860     .ptr = sig,
861     .ptr_size = 0,
862     .size_ptr = NULL
863   };
864   *sig = NULL;
865   return ret;
866 }
867
868
869 /* end of json_helper.c */