diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-08-02 22:16:01 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-08-02 22:16:01 +0200 |
commit | 61450fad8d371a4f75731faa51632229c881ada2 (patch) | |
tree | 3676a07176fc1dfb299014134ef6f6ee11cd804d | |
parent | 3a6ae694ecba19af06d84906facbcb5f7d51d72b (diff) | |
download | exchange-61450fad8d371a4f75731faa51632229c881ada2.tar.gz exchange-61450fad8d371a4f75731faa51632229c881ada2.zip |
-add i18n object syntax check
-rw-r--r-- | src/include/taler_json_lib.h | 10 | ||||
-rw-r--r-- | src/json/i18n.c | 75 |
2 files changed, 59 insertions, 26 deletions
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index bc21957e8..3581252ca 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h | |||
@@ -567,6 +567,16 @@ TALER_JSON_extract_i18n (const json_t *object, | |||
567 | 567 | ||
568 | 568 | ||
569 | /** | 569 | /** |
570 | * Check whether a given @a i18n object is wellformed. | ||
571 | * | ||
572 | * @param i18n object with internationalized content | ||
573 | * @return true if @a i18n is well-formed | ||
574 | */ | ||
575 | bool | ||
576 | TALER_JSON_check_i18n (const json_t *i18n); | ||
577 | |||
578 | |||
579 | /** | ||
570 | * Obtain the wire method associated with the given | 580 | * Obtain the wire method associated with the given |
571 | * wire account details. @a wire_s must contain a payto://-URL | 581 | * wire account details. @a wire_s must contain a payto://-URL |
572 | * under 'url'. | 582 | * under 'url'. |
diff --git a/src/json/i18n.c b/src/json/i18n.c index b92d63ed1..1d3076e2d 100644 --- a/src/json/i18n.c +++ b/src/json/i18n.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of TALER | 2 | This file is part of TALER |
3 | Copyright (C) 2020 Taler Systems SA | 3 | Copyright (C) 2020, 2021 Taler Systems SA |
4 | 4 | ||
5 | TALER is free software; you can redistribute it and/or modify it under the | 5 | TALER 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 | 6 | terms of the GNU General Public License as published by the Free Software |
@@ -24,31 +24,6 @@ | |||
24 | #include "taler_json_lib.h" | 24 | #include "taler_json_lib.h" |
25 | 25 | ||
26 | 26 | ||
27 | /** | ||
28 | * Extract a string from @a object under the field @a field, but respecting | ||
29 | * the Taler i18n rules and the language preferences expressed in @a | ||
30 | * language_pattern. | ||
31 | * | ||
32 | * Basically, the @a object may optionally contain a sub-object | ||
33 | * "${field}_i18n" with a map from IETF BCP 47 language tags to a localized | ||
34 | * version of the string. If this map exists and contains an entry that | ||
35 | * matches the @a language pattern, that object (usually a string) is | ||
36 | * returned. If the @a language_pattern does not match any entry, or if the | ||
37 | * i18n sub-object does not exist, we simply return @a field of @a object | ||
38 | * (also usually a string). | ||
39 | * | ||
40 | * If @a object does not have a member @a field we return NULL (error). | ||
41 | * | ||
42 | * @param object the object to extract internationalized | ||
43 | * content from | ||
44 | * @param language_pattern a language preferences string | ||
45 | * like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1", following | ||
46 | * https://tools.ietf.org/html/rfc7231#section-5.3.1 | ||
47 | * @param field name of the field to extract | ||
48 | * @return NULL on error, otherwise the member from | ||
49 | * @a object. Note that the reference counter is | ||
50 | * NOT incremented. | ||
51 | */ | ||
52 | const json_t * | 27 | const json_t * |
53 | TALER_JSON_extract_i18n (const json_t *object, | 28 | TALER_JSON_extract_i18n (const json_t *object, |
54 | const char *language_pattern, | 29 | const char *language_pattern, |
@@ -92,4 +67,52 @@ TALER_JSON_extract_i18n (const json_t *object, | |||
92 | } | 67 | } |
93 | 68 | ||
94 | 69 | ||
70 | bool | ||
71 | TALER_JSON_check_i18n (const json_t *i18n) | ||
72 | { | ||
73 | const char *field; | ||
74 | json_t *member; | ||
75 | |||
76 | if (! json_is_object (i18n)) | ||
77 | return false; | ||
78 | json_object_foreach ((json_t *) i18n, field, member) | ||
79 | { | ||
80 | if (! json_is_string (member)) | ||
81 | return false; | ||
82 | /* Field name must be either of format "en_UK" | ||
83 | or just "en"; we do not care about capitalization */ | ||
84 | switch (strlen (field)) | ||
85 | { | ||
86 | case 0: | ||
87 | case 1: | ||
88 | return false; | ||
89 | case 2: | ||
90 | if (! isalpha (field[0])) | ||
91 | return false; | ||
92 | if (! isalpha (field[1])) | ||
93 | return false; | ||
94 | break; | ||
95 | case 3: | ||
96 | case 4: | ||
97 | return false; | ||
98 | case 5: | ||
99 | if (! isalpha (field[0])) | ||
100 | return false; | ||
101 | if (! isalpha (field[1])) | ||
102 | return false; | ||
103 | if ('_' != field[2]) | ||
104 | return false; | ||
105 | if (! isalpha (field[3])) | ||
106 | return false; | ||
107 | if (! isalpha (field[4])) | ||
108 | return false; | ||
109 | break; | ||
110 | default: | ||
111 | return false; | ||
112 | } | ||
113 | } | ||
114 | return true; | ||
115 | } | ||
116 | |||
117 | |||
95 | /* end of i18n.c */ | 118 | /* end of i18n.c */ |